看臉的社會代碼也要漂亮才行

圖片1

漂亮整潔的代碼不只給人清爽溫馨的感受,也能有效提升程序員的工做效率,毫無疑問,在這個顏值擔當的時代,代碼也要看臉了,因此如何寫得一手漂亮整潔的代碼是程序員們特別須要get的技能。html

代碼整潔的大前提git

代碼大部分時候是用來維護的,而不是用來實現功能的程序員

這個原則適用於大部分的工程。咱們的代碼,一方面是編譯好讓機器執行,完成功能需求;另外一方面,是寫給身邊的隊友和本身看的,須要長期維護,並且大部分項目都不是朝生夕死的短命鬼。數據庫

對清晰好看代碼的追求精神,比全部的技巧都要重要。設計模式

優秀的代碼大部分是能夠自描述的,好於文檔和註釋微信

當你翻看不少開源代碼時,會發現註釋甚至比咱們本身寫的項目都少,可是卻能看的很舒服。當讀完源碼時,不少功能設計就都清晰明瞭了。經過仔細斟酌的方法命名、清晰的流程控制,代碼自己就能夠拿出來看成文檔使用,並且它永遠不會過時。框架

相反,註釋不能讓寫的爛的代碼變的更好。若是別人只能依靠註釋讀懂你的代碼的時候,你必定要反思代碼出現了什麼問題(固然,這裏不是說你們不要寫註釋了)。函數

說下比較適合寫註釋的兩種場景:工具

  • public interface,向別人明確發佈你功能的語義,輸入輸出,且不須要關注實現。
  • 功能容易有歧義的點,或者涉及比較深層專業知識的時候。好比,若是你寫一個客戶端,各類config參數的含義等。

設計模式只是手段,代碼清晰纔是目的測試

以前見過一些所謂「高手」的代碼都比較抽象,各類工廠、各類繼承。想找到一個實現老是要山路十八彎,一個工程裏大部分的類是抽象類或者接口,找不到一兩句實現的代碼,整個讀起代碼來很不暢。我跟他聊起來的時候,他的主要立場是:保留合適的擴展點,克服掉全部的硬編碼。

其實在我看來,也許他的代碼被「過分設計」了。首先必需要認可的是,在同一個公司工做的同事,水平是良莠不齊的。不管你用瞭如何高大上的設計,若是大多數人都不能理解你的代碼或者讀起來很費勁的話,其實這是一個失敗的設計。

當你的系統內大部分抽象只有一個實現的時候,要好好思考一下,是否是設計有點過分了,清晰永遠是第一準則。

代碼整潔的常見手段

code review

不少大公司會用git的pull request機制來作code review。咱們重點應該review什麼?是代碼的格式、業務邏輯仍是代碼風格?我想說的是,凡是能經過機器檢查出來的事情,無需經過人。好比換行、註釋、方法長度、代碼重複等。除了基本功能需求的邏輯合理沒有bug外,咱們更應該關注代碼的設計與風格。好比,一段功能是否是應該屬於一個類、是否是有不少類似的功能能夠抽取出來複用、代碼太過冗長難懂等等。

我我的很是推崇集體code review,由於不少時候,組裏相對高級的工程師可以一眼發現代碼存在較大設計缺陷,提出改進意見或者重構方式。咱們能夠在整個小組內造成一個好的文化傳承和風格統一,而且很大程度上培養了你們對clean code的熱情。

勤於重構

好的代碼,通常都不是一撮而就的。即便一開始設計的代碼很是優秀,隨着業務的快速迭代,也可能被改的面目全非。

爲了不重構帶來的負面影響(delay需求或者帶來bug),咱們須要作好如下的功課:

  1. 掌握一些常見的「無痛」重構技巧,這在下文會有具體講解。
  2. 小步快跑,不要企圖一口吃成個胖子。改一點,測試一點,一方面減小代碼merge的痛苦,另外一方面減小上線的風險。
  3. 創建自動化測試機制,要作到即便代碼改壞了,也能保證系統最小核心功能的可用,而且保證本身修改的部分被測試覆蓋到。
  4. 熟練掌握IDE的自動重構功能。這些會很大程度上減小咱們的體力勞動,避免犯錯。

靜態檢查

如今市面上有不少代碼靜態檢查的工具,也是發現bug和風格很差的比較容易的方式。能夠與發佈系統作集成,強制把主要問題修復掉才能夠上線。目前美團點評技術團隊內部的研發流程中已經廣泛接入了Sonar質量管理平臺。

代碼整潔的常見技巧

單一職責

這是整潔代碼的最重要也是最基本的原則了。簡單來說,大到一個module、一個package,小到一個class、一個method乃至一個屬性,都應該承載一個明確的職責。要定義的東西,若是不能用一句話描述清楚職責,就把它拆掉。

咱們平時寫代碼時,最容易犯的錯誤是:一個方法幹了好幾件事或者一個類承載了許多功能。

先來聊聊方法的問題。我的很是主張把方法拆細,這是複用的基礎。若是方法幹了兩件事情,頗有可能其中一個功能的其餘業務有差異就很差重用了。另外語義也是不明確的。常常看到一個get()方法裏面居然修改了數據,這讓使用你方法的人情何以堪?若是不點進去看看實現,可能就讓程序陷入bug,讓測試陷入麻煩。

再來聊聊類的問題。咱們常常會看到「又臭又長」的service/biz層的代碼,裏面有幾十個方法,幹什麼的都有:既有增刪改查,又有業務邏輯的聚合。每次找到一個方法都費勁。不屬於一個領域或者一個層次的功能,就不要放到一塊兒。

咱們 team 在code review中,最常被批評的問題,就是一個方法應該歸屬於哪一個類。

優先定義總體框架

我寫代碼的時候,比較喜歡先去定義總體的框架,就是寫不少空實現,來把總體的業務流程穿起來。良好的方法簽名,用入參和出參來控制流程。這樣可以避免陷入業務細節沒法自拔。在腦海中先定義清楚流程的幾個階段,併爲每一個階段找到合適的方法/類歸屬。

這樣作的好處是,閱讀你代碼的人,不管讀到什麼深度,均可以清晰地瞭解每一層的職能,若是不care下一層的實現,徹底能夠跳過不看,而且方法的粒度也會恰到好處。

簡而言之,我比較推崇寫代碼的時候「廣度優先」而不是「深度優先」,這和我讀代碼的方式是一致的。固然,這件事情跟我的的思惟習慣有必定的關係,可能對抽象思惟能力要求會更高一些。若是開始寫代碼的時候這些不夠清晰,起碼要經過不斷地重構,使代碼達到這樣的成色。

清晰的命名

老生常談的話題,這裏不展開講了,可是必需要mark一下。有的時候,我思考一個方法命名的時間,比寫一段代碼的時間還長。緣由仍是那個邏輯:每當你寫出一個相似於」temp」、」a」、」b」這樣變量的時候,後面每個維護代碼的人,都須要用幾倍的精力才能理順。

而且這也是代碼自描述最重要的基礎。

避免過長參數

若是一個方法的參數長度超過4個,就須要警戒了。一方面,沒有人可以記得清楚這些函數的語義;另外一方面,代碼的可讀性會不好;最後,若是參數很是多,意味着必定有不少參數,在不少場景下,是沒有用的,咱們只能構造默認值的方式來傳遞。

解決這個問題的方法很簡單,通常狀況下咱們會構造paramObject。用一個struct或者一個class來承載數據,通常這種對象是value object,不可變對象。這樣,能極大程度提升代碼的可複用性和可讀性。在必要的時候,提供合適的build方法,來簡化上層代碼的開發成本。

避免過長方法和類

一個類或者方法過長的時候,讀者老是很崩潰的。簡單地把方法、類和職責拆細,每每會有立竿見影的成效。以類爲例,拆分的維度有不少,常見的是橫向/縱向。

例如,若是一個service,處理的是跟一個庫表對象相關的全部邏輯,橫向拆分就是根據業務,把創建/更新/修改/通知等邏輯拆到不一樣的類裏去;而縱向拆分,指的是把數據庫操做/MQ操做/Cache操做/對象校驗等,拆到不一樣的對象裏去,讓主流程儘可能簡單可控,讓同一個類,表達儘可能同一個維度的東西。

讓相同長度的代碼段表示相同粒度的邏輯

這裏想表達的是,儘可能多地去抽取private方法,讓代碼具備自描述的能力。舉個簡單的例子

public void doSomeThing(Map params1,Map params2){
   Do1 do1 = getDo1(params1);
   Do2 do2 = new Do2();
   do2.setA(params2.get("a"));
   do2.setB(params2.get("b"));
   do2.setC(params2.get("c"));
   mergeDO(do1,do2);
   }
   private void getDo1(Map params1);
   private void mergeDo(do1,do2){...};

相似這種代碼,在業務代碼中隨處可見。獲取do1是一個方法,merge是一個方法,但獲取do2的代碼卻在主流程裏寫了。這種代碼,流程越長,讀起來越累。不少人讀代碼的邏輯,是「廣度優先」的。先讀懂主流程,再去看細節。相似這種代碼,若是可以把構造do2的代碼,提取一個private 方法,就會舒服不少。

以上這些優化管理代碼的方法可以有效使咱們的代碼看起來更清爽更漂亮,仍是那句話,這毫不僅僅是顏值問題,這更是一個工做效率的問題,不想在冗雜的代碼裏掙扎就不妨嘗試一下上面的方法吧,也許你會發現something amazing.

閱讀原文

微信關注公衆號:Aspose 知足一切文檔需求

相關文章
相關標籤/搜索