阿里JAVA開發手冊零度的思考理解(一)


轉載請注明原創出處,謝謝!

緣由

阿里JAVA開發手冊已經發表有很長時間了,值得認真研究思考推廣

  • 阿里官方的Java代碼規范標准,這份開發手冊不僅規范了一些開發細節,也提出了很多工程開發的哲學,值得好好閱讀。

  • 可謂包羅萬象,幾乎日常Java開發中方方面面都有所涉及。

  • 每一條都是前人踩過的坑,通過血的教訓總結出來的。

  • 能公布出來真是造福全部Java開發者。

  • 開發手冊詳細列舉如何開發更加高效,更加容錯,更加有協作性,力求知其然,更知其不然,結合正反例,提高代碼質量。比如,異常日志處理時的各種不規范行為;集合轉換的各種坑;創建線程池出現的等待隊列OOM等。

的確阿里JAVA開發手冊值得我們好好閱讀和思考,每一條都是前人踩過的坑,通過血的教訓總結出來的。所以今天就其中一點自己的思考理解進行分享。

阿里JAVA開發手冊

看完這條,個人覺得主要是圈復雜度,由於代碼是人寫的,並且需要人來進行維護,如果足夠的復雜的話,那么編寫出現錯誤的可能性都很大,並且維護理解起來難度也非常高,以及后期如果需要擴展本來就很復雜再加一個很簡單的功能都變得很困難(相信大家一定都有這樣的經歷)。

圈復雜度

圈復雜度(Cyclomatic complexity)是一種代碼復雜度的衡量標准。
在軟件測試的概念里,圈復雜度用來衡量一個模塊判定結構的復雜程度,數量上表現為獨立線性路徑條數,即合理的預防錯誤所需測試的最少路徑條數。圈復雜度大說明程序代碼可能質量低且難於測試和維護,根據經驗,程序的可能錯誤和高的圈復雜度有着很大關系。

看看上面阿里JAVA開發手冊里面提到的,如果非得使用if()...else if()...else...方式表達邏輯,【強制】避免后續代碼維護困難,請匆超過3層。如果超過3層的if-else的邏輯判斷代碼可以使用衛語句、策略模式、狀態模式等來實現。

其實在我看來,使用衛語句、策略模式、狀態模式就是來降低圈復雜度,讓代碼更加簡單,這樣不管是編寫代碼人員以及維護人員都可以非常方便了解到本質意思。

雖然阿里JAVA開發手冊提到的是if()...else if()...else...方式表達邏輯,延伸下,關於多次嵌套循環等道理也一樣,需要考慮優化的。

思路分析

判斷樹

如上圖,其實看起來就是一顆樹結構,相對來說其實比較復雜了,優化的思路其實就是把樹結構變成順序結構即可,那樣條理就清晰了,總體思路是這樣的,下面看看使用衛語句、策略模式、狀態模式怎么達到的。

衛語句

衛語句?衛語句就是把復雜的條件表達式拆分成多個條件表達式,比如一個很復雜的表達式,嵌套了好幾層的if - then-else語句,轉換為多個if語句,實現它的邏輯,這多條的if語句就是衛語句。

其中衛語句示例如下:

public void today() {
    if (isBusy()) {
        System.out.println("change time.");
        return;
    }
    if (isFree()) {
        System.out.println("go to travel."); 
        return;
    }
    System.out.println("stay at home to learn Alibaba Java Coding Guidelines.");
    return;
}

其實這個比較簡單,每一個if對應葉子節點的一條路徑(每個if基本就return了)。

策略模式

概述:使用這個模式來將一組算法封裝成一系列對象。通過傳遞這些對象可以靈活的改變程序的功能。

策略模式比較有名的就是諸葛亮的三個錦囊妙計說起,如圖:

諸葛亮為什么要這么麻煩,做三個錦囊?他完全可以只做一個錦囊,將這三個妙計都寫在它上面。可他沒有這么做,而是正確的運用了策略模式做了三個錦囊。這樣做的好處十分明顯諸葛亮一個錦囊寫一個妙計,他的思路十分清晰,不會三個計策相互混亂。趙雲看妙計的時候也十分方便,什么時候看哪個妙計,使用十分方便,如果三個妙計混在一起,他就沒這么方便了。

在JDK中java.util.Comparator#compare()就是使用的策略模式,比如我們經常對商品進行排序,條件有很多啊,按照商品瀏覽量、價格、更新時間、【價格、時間】、【瀏覽量、更新時間】(進行升序、降序操作)其實這個也是上面那顆樹,需要做的就是每次取其中一條葉子節點。很多時候這些判斷都是寫在一個公用的方法里面,進行大量的判斷之后寫排序,而JDK怎么做的呢?把變化的比較判斷拿出來,其實判斷樹中每個葉子結點就是一種策略,想象我們平時怎么做的呢? 都是把Comparator#compare()寫好(可能有很多實現Comparator接口的排序算法)每次我們調用的時候選擇其中一種即可。

與衛語句不同的是,衛語句把每一個if對應葉子節點的一條路徑。而策略模式是所以葉子都在實現Comparator接口了,具體開始用那個是調用的直接用(所以不會像衛語句那樣看見很多if了)

狀態模式

概述:當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變了其類。主要解決的是對象的行為依賴於它的狀態(屬性),並且可以根據它的狀態改變而改變它的相關行為。

  1. 封裝了轉換規則。
  2. 枚舉可能的狀態,在枚舉狀態之前需要確定狀態種類。
  3. 將所有與某個狀態有關的行為放到一個類中,並且可以方便地增加新的狀態,只需要改變對象狀態即可改變對象的行為。
  4. 允許狀態轉換邏輯與狀態對象合成一體,而不是某一個巨大的條件語句塊。
  5. 可以讓多個環境對象共享一個狀態對象,從而減少系統中對象的個數。

由於狀態模式是封裝了轉換規則,所以一般樹的深度最少需要2層以及上,個人理解的感覺就是一個流程了,比如*水低於0度是冰的狀態--> 大於0度又變成液態--> 100度又變成沸騰的狀態

狀態模式與策略模式很像,策略模式是外驅動,而狀態模式是內驅動。本質也是把判斷樹里面只取其中一條葉子的路徑。

狀態模式有一個明顯的缺點:狀態模式對"開閉原則"的支持並不太好,對於可以切換狀態的狀態模式,增加新的狀態類需要修改那些負責狀態轉換的源代碼,否則無法切換到新增狀態,而且修改某個狀態類的行為也需修改對應類的源代碼。

程序員笑話

老婆給當程序員的老公打電話:下班順路買十個包子,如果看到賣西瓜的,買一個。當晚老公手捧一個包子進了家門…老婆怒道:你怎么只買一個包子?!老公甚恐,喃喃道:因為我真看到賣西瓜的了。”

如果使用策略模式就簡單了,2條信息,1:買十個包子。2:買一個西瓜,沒有就算了。
雖然是個笑話,但是順序的就是比判斷的要簡單。

總結

  • 圈復雜度概念
  • 衛語句
  • 策略模式
  • 狀態模式

匯總:本質就是把較深的判斷樹,使用的時候,就是把判斷樹結構變成順序結構即可,就是給出每個葉子的路徑而不需要看起來是一顆復雜的樹結構。

思考

阿里JAVA開發手冊

這是阿里JAVA開發手冊其中一條明細,為什么呢,結果是啥,怎么出乎意料啦??期待你的留言和分析!!!


上面的一些分析都是個人自己的理解和思考,如果發現有不對的希望留言指出,謝謝!!!
如果讀完覺得有收獲的話,歡迎點贊加關注。


個人公眾號

匠心零度公眾號.jpg


免責聲明!

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



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