代码 | 一天一点代码坏味道(1)
【代碼精進】|?總結/Edison Zhou
作為一個后端工程師,想必在職業生涯中都寫過一些不好維護的代碼。本文是我學習《代碼之丑》的學習總結,今天第一天發車,先來看看在命名上的一些常犯的壞味道。
0為何要品代碼壞味道
Martin Flower在《重構》一書中給不好維護的這一類代碼取了一個藝名:代碼的壞味道,而這些壞味道一旦堆積多了,整個系統雖然還是可以平穩運行,但是就是讓程序員不敢動,更別提重構了。
因為......
哎,都是打工人,誰容易啊?
1不精準的命名
直接來看一段壞味道代碼:
public void ProcessChapter(long chapterId) {Chapter chapter = _repository.GetChapterById(chapterId);if (chapter == null){throw new ArgumentException($"Unknown chapter [{chapterId}]");}chatper.TransactionState == TransactionState.TRANSLATING;_repository.UpdateChapter(chapter); }此段代碼存在的問題:方法名ProcessChapter命名過于寬泛,不能精準描述意圖,是代碼難以理解的根源所在。
同類型的詞匯請各位看官自查,例如:data,info,flag,process,handle,build,maintain,manage,modify等等等,它們應該都出現在你我的項目代碼中過。
重構方法:命名需要能夠描述出這段代碼在做的事情,根據代碼的邏輯含義,調整其命名為 ChangeChapterToTranslating,是不是無論誰來接手這個方法的代碼就都好理解了?
一個好的名字應該是描述意圖,而非細節的。那么,我們再重構一下,結合具體的業務,將其命名改為 StartTranslation,即開始翻譯,是不是就更能體現業務含義了?
public?void?StartTranslation(long?chapterId) {...... }2用技術術語命名
這是一個我也經常犯的壞味道:
List<Book> bookList = service.GetBooks();這個bookList的原因是因為它的類型是List,還有xxxDict,xxxMap等,它不費腦子,但它卻只是一種基于實現細節的命名方式。
重構方法:使用面向意圖的名字。
又如,如果在業務代碼中出現了Redis這類的中間件:
通常來說,這里只是需要一個緩存,那么Redis也就只是這個緩存的一個具體實現,如果換為其他的NoSQL存儲如Memcached呢?
因此,我們其實缺少了一個模型,在這里其實就是一個接口,假設這個接口如下:
public interface ICacheClient {object Get(string key);void Put(string key, object value); }使用接口替代之后,我們就是面向接口編程了:
技術人喜歡用技術名詞命名,因為這是大家習慣的語言。但是,對于業務項目而言,需要盡可能將技術術語隔離開,因為業務語言才是最好的命名方式。
DDD領域驅動設計方法就號召我們建立統一語言,這個統一語言是可以和業務部門的人員無障礙交流的語言,換句話說,也就是業務語言。另一方面來看,這就倒逼技術團隊需要建立團隊的業務詞匯表,讓團隊成員達成統一共識,這也是要統一共識需要付出的額外成本,但是這個成本是有價值的。
編寫可維護的代碼之路
比如,我們經常會寫下面的參數命名:
public?void?ApproveChapter(long?chapterId,?long?userId)? {... }假設通過業務分析,這里的user其實是審核人,而我們為了方便就命名為userId了。那么,將其改為reviewerUserId是不是更加貼近業務?
在實際開發中,這樣子的例子還有很多。
3亂用英語來命名
作為一個受了多年義務教育與高等教育的我們來說,English一點也不陌生,但是就是始終感覺用不到位。
如果能用中文來命名,我們是不會到處查單詞用英文來命名的,但是,用中文,沒有B格啊,我放棄!
違反語法規則的命名
類是一個名字,表示一個對象。而方法名一般是一個動詞或動賓短語,表示一個動作。但是,有時候,我們喜歡忽視這個規則。
CompletedTranslate 是個啥(四不像結構)?改為 CompleteTranslation 是不是好一點(動賓結構)?
又比如,一個方法名叫 ReTranslation(額,Translation好像是個名詞吧),意為重新翻譯,但作為方法名,應該選擇動詞,改為 ReTranslate 會更好(Translate是個動詞,棒!)。
不準確的英語詞匯
由于英文單詞可以有多個含義,且在不同場景下含義也可以不同,這就難為我們中國人了。
比如,下面的一個枚舉,想表達的是審核狀態:
public enum ChapterAuditStatus {PENDING,APPROVED,REJECTED }但是,Audit這個詞雖然也有審核的含義,但是它更偏重于財務審計這塊,而這里的業務是文稿的審核。
因此,改為Review可能會更加貼近一些:
從上也可以看出,技術團隊建立一個統一的業務詞匯表,很有必要!這是集體的智慧,而非個體的。一個人的英語可能不太好,但是一群人在一起,總有那么一個會找出合適的說法。
英語單詞拼寫錯誤
這個,我相信大家各自項目中都有不少拼錯的案例,很多人查了單詞之后,都還是拼錯...?
但是,往往很多時候就是差了或者多了那么一個字母,就會讓人懵逼了。
4小結
本文總結了命名相關的兩類壞味道,一是命名是否具有業務含義,二是命名是否符合英語語法。
最后,感謝鄭曄老師的這門《代碼之丑》課程,讓我受益匪淺!我也誠心把它推薦給關注EdisonTalk公眾號的各位童鞋!
參考資料
鄭曄,《代碼之丑》(推薦訂閱學習)
Martin Flower著,熊杰譯,《重構:改善既有代碼的設計》(推薦至少學習第三章)
????掃碼訂閱《代碼之丑》
????點擊購買《重構:改善既有代碼的設計》
年終總結:Edison的2020年終總結
數字化轉型:我在傳統企業做數字化轉型
C#刷題:C#刷劍指Offer算法題系列文章目錄
技術管理:IT技術人的技術管理學習進階
商業知識:IT技術人的底層商業知識兵器庫
.NET大會:2020年中國.NET開發者大會PDF資料
????掃碼關注EdisonTalk
不變的依舊是分享!
總結
以上是生活随笔為你收集整理的代码 | 一天一点代码坏味道(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c#爬虫-1688官网自动以图搜图
- 下一篇: 小心 Enum Parse 中的坑