dotNET Core:编码规范
在項目開發過程中,由于時間緊、任務重,很容易導致面向功能編程。實現相同的功能,代碼可以寫的很優雅,也可以寫的很晦澀和復雜。現在的工作,都需要進行團隊協作,代碼就需要有一定的規范進行指引,因為我們需要寫出讓人可以輕易讀懂的代碼,而不僅僅是機器。
規范沒有絕對的標準,遵循大部分人都認可的一種方式就可以了,保持統一。比如在 dotNET Core 中,我們可以參考下 dotNET Core 的源碼,最終制定一個適合團隊的規范即可。
下面是我理解的正確的一些規范:
基本準則
1、命名的規范分為兩種:Pascal(大駝峰)和駝峰(小駝峰),示例如下:
? Pascal:UserName
? 駝峰:userName
2、命名要有意義,需要看到名稱知其含義。少用拼音和匈牙利命名法。
| Int price=20; | √ |
| UserInfo userInfo=GetUserInfo(userId); | √ |
| Int p=20; | × |
| Int intPrice=20; | × |
3、對于類的成員變量,用this關鍵字,增強代碼可讀性。
4、對于基類的成員變量,用base關鍵字,增強代碼可讀性。
名稱規范
好的名稱可以讓我們減少很多不必要的注釋,可以讓代碼閱讀者很容易就理解代碼的意思。但命名不是一件容易的事情,在命名的時候,通常伴隨著我們對代碼邏輯的思考。比如:如果你不能給一個函數很準確地命名,那可能這個函數的職責不單一,做的事情太多,才導致一個名稱很難概括,意味著代碼可能需要重構。好的命名是我們寫好代碼的基礎。
命名空間
命名空間采用Pascal命名法:
namespace?Fw.Application{} namespace?Fw.SmartFlow.Acitivity{}實際工作中,我們會將很多邏輯上屬于同一類的文件,在物理上分成不同的目錄,這時建議修改命名空間為相同的命名空間。
類
類采用Pascal命名法:
public?class?UserService{}類是對屬性和方法的封裝,類有很多的種類:
跟數據庫表對應的實體類
處理業務邏輯的業務類
提供擴展方法的擴展類
接口層的數據傳輸類
不同的種類可以約定俗成地進行一些名稱的約束,比如擴展類用 Extension 結尾、接口層的使用 Request、Response 結尾,等等,這樣在閱讀代碼時就知道什么類的職責是什么。
接口
接口采用大寫I+Pascal命名法:
public?interface?IUserService{}方法
方法采用Passcal命名法:
public?string?GetUserName(){}方法的命名需要比較具體,越抽象的名稱越難以理解。例如,InitData() 就是一個不太好的名稱,改成 InitConfiginfo() 會更好些。另外,方法的命名在同一類型的語義下要保持一致,在一些項目中看到查找類的方法,有 GetXXX、QueryXXX、FindXXX 等等。五花八門的方式會提升閱讀的成本。
變量
變量分為:類變量、靜態類變量、只讀變量、靜態只讀變量、方法變量。
類變量:
private?string?_userName;類變量只能使用 private 修飾符,如果需要暴漏出去,或是給子類使用,使用屬性來進行封裝。
靜態類變量、只讀變量、靜態只讀變量:
private?static?readonly?ResourceManager?_resourceManager; public?static?readonly?IRouter?Instance?=?new?MockRouter();? 修飾符為 private: _ + 駝峰命名法;
? 修飾符為 public: Pascal 命名法;
? 修飾符為 protected:Pascal 命名法;
方法變量:
bool?isCheck;常量:
常量采用Pascal命名法:
public?const?string?AuthorizationFilter?=?"Authorization?Filter";屬性:
屬性采用 Pascal 命名法:
public?BasicApiContext?DbContext?{?get;?}參數
參數采用駝峰命名法:
public?List<BizApp>?GetBizAppList(string?userId,DeviceType?deviceType)注釋規范
注釋是一把雙刃劍,當代碼中存在大量的注釋的時候,我們第一反應會先看注釋,并會默認注釋中寫的內容是對的,真實情況是注釋往往會給我們錯誤的指導。有兩個原因:
當代碼邏輯發生變化時,只修改了代碼,注釋沒有調整;
不同的人員都對注釋進行編輯,慢慢注釋會變得和代碼不匹配。
Martin Fowler 在他的經典書籍 《重構》 中也提到過多的注釋是一種壞味道的體現,他認為,當你覺得需要寫注釋的時候,應該先想想是不是可以進行重構。那是不是程序中就不應該出現注釋呢?當然不是,我認為下幾種情況是需要寫注釋的:
時間緊急,臨時寫的一些 ”爛代碼“,需要寫注釋,說明原因,一般需要加上 TODO ;
復雜算法類的方法,可以寫注釋說明邏輯;
寫的是偏底層的類庫,對外暴露的方法需要寫注釋,調用方能方便在智能提示中顯示;
如果你的能力寫不好代碼,那還是先把注釋寫上吧。
異常規范
異常的目的是用來報告錯誤,這也是他的唯一目的,所以避免在返回值中來返回錯誤信息,所有的地方都應該使用拋異常的方式來報告錯誤;
使用拋異常的方式可以防止錯誤的操作繼續執行;
要能夠預估到會出現什么異常,知道是什么類型的異常,才 Try 住做相關的處理;
最終用戶友好和對開發者友好;
暴漏問題比隱藏問題要好,隱藏問題只會導致更嚴重的問題。
詳細的異常處理可以參考之前的文章:
dotNET:怎樣處理程序中的異常(理論篇)?
dotNET:怎樣處理程序中的異常(實戰篇)?
空行規范
空行規范是一個很簡單的規范,就是在每個方法中,代碼應該按照不同邏輯的邏輯塊進行分割顯示,雖然簡單,但如果不注意,還是會對代碼的閱讀帶來很大的障礙。下面看看 dotNET Core 的源碼 CreateDefaultBuilder 方法:
public?static?IHostBuilder?CreateDefaultBuilder(string[]?args) {var?builder?=?new?HostBuilder();builder.UseContentRoot(Directory.GetCurrentDirectory());builder.ConfigureHostConfiguration(config?=>{config.AddEnvironmentVariables(prefix:?"DOTNET_");if?(args?!=?null){config.AddCommandLine(args);}});builder.ConfigureAppConfiguration((hostingContext,?config)?=>{var?env?=?hostingContext.HostingEnvironment;config.AddJsonFile("appsettings.json",?optional:?true,?reloadOnChange:?true).AddJsonFile($"appsettings.{env.EnvironmentName}.json",?optional:?true,?reloadOnChange:?true);if?(env.IsDevelopment()?&&?!string.IsNullOrEmpty(env.ApplicationName)){var?appAssembly?=?Assembly.Load(new?AssemblyName(env.ApplicationName));if?(appAssembly?!=?null){config.AddUserSecrets(appAssembly,?optional:?true);}}config.AddEnvironmentVariables();if?(args?!=?null){config.AddCommandLine(args);}}).UseDefaultServiceProvider((context,?options)?=>{var?isDevelopment?=?context.HostingEnvironment.IsDevelopment();options.ValidateScopes?=?isDevelopment;options.ValidateOnBuild?=?isDevelopment;});return?builder; }想想看,上面代碼中如果去掉空行會讀起來是什么樣的感受?
日志規范
在一個完整的系統中,日志非常的重要。在 dotNET Core 中自帶了日志功能,當然我們也可以使用第三方的 NLog、Serillog 等。
這些日志框架都提供日志級別功能,比如:INFO、DEBUG、WARN 和 ERROR 等,這些級別對程序出錯時的排查非常有用,所以在記錄日志時一定不要都使用 INFO 或者都使用 ERROR 了。
除了級別,日志的類型有這么幾類:
操作日志
業務日志
錯誤日志
操作日志
系統中所有的操作的都記錄下來,包括登錄、數據的增刪改等,主要用來做審計,數據異常操作時的追責等。
隨著時間的推移,日志的數據量會越來越大,所以需要考慮存儲的方式,比如階段性地將歷史日志進行存檔。
業務日志
用戶在界面中輸入數據,點擊一個按鈕,程序中會進行一系列的處理最終返回結果給用戶,在這個過程中對一些關鍵的業務信息進行記錄,可以在系統出現問題時方便排查和追蹤。
錯誤日志
錯誤日志的主要目的就是排錯,所以記錄的信息一定要是對排錯有幫助的信息,盡可能地記錄詳細,比如整個堆棧信息、調用鏈等。比如,你去進行錯誤排查時,發現記錄的信息是”未將對象引用到對象的實例“,你依然不知道錯誤的原因是什么。
總結
談及代碼的時候,都會去聊架構、模式,這些固然重要,但編碼習慣和規范也不可小視。一份產品的代碼怎樣才能變得越來越好,這需要團隊每個人成員共同的努力,一個人掉鏈子,很容易就形成破窗效應,導致壞味道越來越多。
寫好的代碼,是每個有追求的技術人的使命和職責。
希望本文對您有所幫助。
總結
以上是生活随笔為你收集整理的dotNET Core:编码规范的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 跟我一起学.NetCore之配置变更监听
- 下一篇: .NET 5 自身就是一个 .NET S