3. 項目管理規范 && 命名方式規范


項目管理和命名方式都是“規范”的問題,部分公司會書寫這方面的規范文檔,以保證大家寫出來的代碼符合同一規范。這里只討論常用的規范方式。

項目管理

項目管理這一塊,涉及到解決方案中的各個概念,“解決方案”、“項目”、“文件夾”、“文件”(含說明性文檔)。其中,解決方案包含項目,項目包含文件夾,文件夾包含文件。

解決方案 && 項目

一般來說一個解決方案是一個產品(網站、APP、桌面程序、類庫等等)。
“項目”是一個個.csproj,最簡單的就是一個解決方案、一個項目,完成開發。但大家並不會這樣做,我們會把一個項目拆分成多個項目,在不同的項目中完成不同的功能,然后通過引用的方式完成不同項目之間的“粘連”。
為什么要這樣做呢?一個原因是提高代碼的可讀性。比如最傳統的三層架構,視圖(eg.網站)是一個項目,業務邏輯(BLL)是一個項目,數據庫操縱(DAL)是一個項目。將不同的職責放到不同的項目中,管理、優化起來更加方便,代碼更加清晰。
另一個原因是,一個龐大的項目往往由多個開發組、多個開發者去開發和維護。將項目拆解成一個個獨立的項目(甚至獨立的解決方案),有利於多個開發者的工作。可能產品的部分功能由開發組A完成,另一部分功能由開發組B完成,而兩個開發組的代碼對對方來說都是不可見的。
所以“拆解”項目不要吝嗇,根據業務、邏輯,最大化的去拆分項目,對未來產品的功能拓展和代碼維護都有很大好處。
解決方案的命名一般和產品息息相關,比如Taobao、Wechat。而項目的命名,可以在解決方案的基礎上加一些“說明”,比如Wechat.Mobile、Wechat.Tool,添加的內容概況項目的定位。
剛開始如果沒有辦法去很好的組織項目,可以參考其他優秀的項目,github上面有很多優秀的開源的項目,他們的項目是怎么組織的,代碼是怎么寫的,都非常值得學習,比如:vscodeaspnetboilerplateNewtonsoft.Json。多看高Star的項目多學習。
對於產品名字過長的問題,在命名時,可以采用“縮寫”。比如“aspnetboilerplate”,項目名都是“Abp.xxx.xxx”,用“Abp”代替了“aspnetboilerplate”。這都還不算很長的產品名稱,業務系統很多都是“XXXXX系統”, 比如我之前開發的“生態監測管理系統”,英文翻譯為“Ecological Monitoring Management System”,如果我們不進行縮寫,解決方案的名稱為“EcologicalMonitoringManagementSystem”,項目的名稱是“EcologicalMonitoringManagementSystem.EntityFramework”,類名為“EcologicalMonitoringManagementSystem.EntityFramework.EntityMapper.Devices.DeviceCfg” ——————————哇,這簡直是個災難!又臭又長。
所以我們要進行縮寫,將“Ecological Monitoring Management System”寫成“EMMS”。

文件夾 && 文件

一個項目中可以有文件夾、文件,那它們又是怎樣擺放的呢?我一般將程序的入口、配置的內容放在根目錄,把“同一類型”的文件放在同一文件夾下。
比如控制台程序中的Program.cs、ASP .NET Core中的appsettings.json、Startup.cs,都適合放在項目的根目錄。
同一類型、同一功能的內容,比如“完成發送短信的功能”、“定義產品表”,涉及的所有內容,可以放在同一文件夾中。
“定義產品表”的文件夾中,可以包含產品表的定義、產品表的MapperConfiguration、數據庫Configuration、Dto等等。
“完成發送短信的功能”,可以包含發送短信的接口、發送短信的實現(多個短信服務平台)、發送短信的統一方法(包含業務邏輯)等。可能還會有一些README文件,用來備注一些關於發送短信信息。
文件夾的命名肯定以“貼近”其中的內容為目標。文件夾的命名的單復數,可以根據內容來判斷:如果文件夾像一個工廠一樣,整體完成一個零件,則可以取這個零件名稱的單數形式作為文件夾的命名,比如“定義產品表”-Product;如果文件夾完成了同一目的的不同實現,則可以取復數,比如“完成發送短信的功能”-SendMessages。
一般一個.cs文件放一個類,類的命名為單數,且文件和類同名。有些開發喜歡把接口和實現類、類和它包含的枚舉值放在一起,是個人習慣問題,我個人不推薦這樣做。
一些同功能的類使用同樣的命名結尾,比如“XXXBuilder”、“XXXConfiguration”、“XXXHelper”。
這里我展示一些我開發的項目中的文件擺放。

類、變量、方法命名方式

我們先直觀感受下不同語言的命名方式:
java(來自Android開發之onClick事件的三種寫法


package a.a;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
 
public class AActivity extends Activity {
	/** Called when the activity is first created. */
 
	EditText Ev1;
 
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
 
		Ev1 = (EditText)findViewById(R.id.editText1);  
 
		//第一種方式  
		Button Btn1 = (Button)findViewById(R.id.button1);//獲取按鈕資源  
		Btn1.setOnClickListener(new Button.OnClickListener(){//創建監聽  
			public void onClick(View v) {  
				String strTmp = "點擊Button01";  
				Ev1.setText(strTmp);  
			}  
 
		});  
 
		//第二種方式  
		Button Btn2 = (Button) findViewById(R.id.button2);//獲取按鈕資源  
		Btn2.setOnClickListener(listener);//設置監聽  
 
	}
 
	Button.OnClickListener listener = new Button.OnClickListener(){//創建監聽對象  
		public void onClick(View v){  
			String strTmp="點擊Button02";  
			Ev1.setText(strTmp);  
		}  
 
	};
 
 
	//第三種方式(Android1.6版本及以后的版本中提供了)  
	public void Btn3OnClick(View view){  
		String strTmp="點擊Button03";
		Ev1.setText(strTmp);
 
	}  
}

python

import requests        #導入requests包
import json
def get_translate_date(word=None):
    url = 'url'
    From_data={}
    #請求表單數據
    response = requests.post(url,data=From_data)
    #將Json格式字符串轉字典
    content = json.loads(response.text)
    print(content)
    #打印翻譯后的數據
    #print(content['translateResult'][0][0]['tgt'])
if __name__=='__main__':
    get_translate_date('......')

C#(來自在C#中,Json的序列化和反序列化的幾種方式總結

Student stu = new Student()
 {
	 ID = 1,
	 Name = "曹操",
	 Sex = "男",
	 Age = 1000
 };
//序列化
DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(Student));
MemoryStream msObj = new MemoryStream();
//將序列化之后的Json格式數據寫入流中
js.WriteObject(msObj, stu);
msObj.Position = 0;
//從0這個位置開始讀取流中的數據
StreamReader sr = new StreamReader(msObj, Encoding.UTF8);
string json = sr.ReadToEnd();
sr.Close();
msObj.Close();
Console.WriteLine(json);


//反序列化
string toDes = json;
//string to = "{\"ID\":\"1\",\"Name\":\"曹操\",\"Sex\":\"男\",\"Age\":\"1230\"}";
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(toDes)))
{
	DataContractJsonSerializer deseralizer = new DataContractJsonSerializer(typeof(Student));
	Student model = (Student)deseralizer.ReadObject(ms);// //反序列化ReadObject
	Console.WriteLine("ID=" + model.ID);
	Console.WriteLine("Name=" + model.Name);
	Console.WriteLine("Age=" + model.Age);
	Console.WriteLine("Sex=" + model.Sex);
}
Console.ReadKey(); 

可以看出,不同的語言寫法差異很大,一方面是來自語法、格式本身不同,一方面是不同語言的開發者的命名規范不同。
C#的命名方式也有很多,這里我只描述我最常用的方式。
所有多單詞的連接,都使用駱駝命名法。即"Get Your Information",變為"GetYourInformation"。
類中的屬性、方法名,以大寫字母開頭,字段以小寫字母開頭(一些開發喜歡以下划線開頭)。
接口以“I”開頭,比如“ISendMessage”。
命名方式,可以選擇一種自己覺得最舒適的規范,然后一直遵守它。
舉個例子:

public class StudentByINotifyPropertyChanged: INotifyPropertyChanged
{
	public event PropertyChangedEventHandler PropertyChanged;
	//實現INotifyPropertyChanged接口
	private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
	{
		if (PropertyChanged != null)
		{
			PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
		}
	}

	//私有字段小寫
	private string sex;
	private string name;

	//公開屬性大寫
	public string Sex
	{
		get { return sex; }
		set
		{
			sex = value;
			NotifyPropertyChanged("Sex");
		}
	}

	public string Name
	{
		get { return name; }
		set
		{
			name = value;
			NotifyPropertyChanged("Name");
		}
	}
}

INotifyPropertyChanged是接口,以“I”開頭。“StudentByINotifyPropertyChanged”這個名字不是太好,實際上這是“StudentViewModel”(MVVM相關概念)。
私有字段小寫開頭,公有屬性大寫開頭。如果將Name拆分為“姓”、“名”,則私有字段是“lastName”,“firstName”,公有屬性為“LastName”、“FirstName”。
有方法“獲得姓名”,則應該命名為“GetName”或者“GetFullName”。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM