我的程式碼會說話 第4章 理論知識的補充
第四章可與其他經典軟體書籍《Clean Code》 與 《Code Complete》對照看,其他書籍翻譯太複雜無法理解的時候,來看第四章作者寫得比較簡潔,會比較容易懂。
4.1 物件導向的基礎知識
物件導向主張一切皆物件。
4.1.1 封裝
把物件的資料與行為封裝在一起,外部透過抽象的介面存取物件,進而達到隱藏物件細節的目的。
對於封裝本質不夠了解,會出現以下的誤解
1.類別就是帶有函數的結構
類別是一個把屬性和行為封裝在一起的集合,並且透過隱藏細節向外提供介面,使資料之間的存取透過介面完成。
2.介面如果增加了變數就會變成抽象類別
介面中只能有抽象方法,抽象類別中可以有具體的實作方法,抽象類別可以有建構子,而介面中則沒有。
介面中一樣可以定義常數。繼承抽象類別只能繼承一個,實作介面可以實作多個。
4.1.2 繼承
程式碼中建構繼承關係是為了提高程式碼的重複使用性。
使用繼承時必須注意下面這些事項:
1.菱形繼承問題
大多數語言不支援多重繼承,也就不存在菱形繼承問題。
2.不希望被繼承
3.不需要的繼承
4.訪問父類別
java透過super關鍵字訪問父類別。
5.訪問祖父類別
訪問祖父類別代表繼承體系出現問題。
6.訪問子孫類別
樣板方法模式父類別採用抽象方法呼叫,而子類別對抽象進行實作。
除了樣板方法模式之外,父類別不應該呼叫子類別自行定義的方法。
7.錯誤的繼承 (?)
8.相似的介面
一個類別實作了若干相似的介面,類別中的方法就會混亂。
4.1.3 多型
同一個介面表述相同類型、不同實體的處理方式稱為多型。採用多型可讓呼叫者的程式碼只關心介面,而不必關心介面的實作。
多型的表現方式是overload 與override
override
override 採用同一個方法署名,對方法進行重新定義。
overload
overload 採用同樣的名稱,採用不同的署名對方法進行重新定義。編譯器會根據參數的個數和參數的型別進行合適的呼叫。
4.2 設計的基本原則
4.2.1 單一職責原則
每個類別都應該只有一個職責,所有職責都應該被封裝在這個類別中。
一個類別不能有多個職責。
同一個類別的職責不應該定義到別的類別。
引起程式碼變更的原因應該只有一個,如果多個原因會引起程式碼的變更,會導致
程式碼的外部依賴度比較高
程式碼的穩定性比較差
單一職責原則同樣適於方法。
4.2.2 開放封閉原則
程式碼應該對擴展開放,對變更封閉。
擴展開放是指當程式碼增加功能時,由於已經預設擴展的介面,擴展時不需要對既有的程式碼產生很大的影響。
變更封閉代表程式碼的功能模組已經拆分,所以不至於因為變更而引起大面積的程式碼變動。
4.2.3 Liskov替換原則
任一個子類別都應該能夠替代其父類別。
若是子類別不能夠替代父類別,或是父類別給子類別遺留了它並不需要的行為,代表繼承關係違反Liskov替換原則。
4.2.4 介面隔離原則
一個類別對於另一個類別的依賴,應該取決於其最小介面,應該將不同的職責分成小介面,客戶端不應該依賴於它們用不到的方法。
4.2.5 依賴倒置原則
上層不應該依賴於下層,二者都應該依賴於介面,抽象不依賴於實作,實作應該依賴於抽象。
4.2.6 德摩特爾法則
The Law of Demeter 又稱最小知識原則。一個物件對另一個物件的內部了解越少越好。
一個類別A可以訪問直接相關的類別B,類別A不可以透過類別B訪問類別C。
德摩特爾法則可使程式碼耦合度降低,缺點是會引進大量中間類別。
4.2.7 不要自我重複
去掉程式碼中重複的部分。
4.3 圈複雜度
圈指程式碼中的邏輯形成圈狀的路徑如分支、迴圈。
圈複雜度的高低與Bug多少有明顯的關係,巢狀更是大幅提高圈複雜度的因素。
縮減圈複雜度要盡可能減少巢狀的使用,去掉判定、迴圈語句。
留言
張貼留言