【軟件構造】第四章第一節 面向可理解性的構造
第四章第一節 面向可理解性的構造
Outline
- 代碼可理解性
- 編碼規範
Notes
## 代碼的可理解性
代碼的可理解性可以理解為代碼的可讀性。具體來說,可從以下幾個方面來看:
- 是否遵循特定的命名規範?
- 是否足夠的註釋/說明?
- 是否足夠的內聚性?
- 方法是否太長或太短、是否容易理解?
【代碼質量測量:WTFs / min】
簡單來說,好的代碼讓人更容易理解,其他程序員在閱讀時就會發出更少的WTF(What the fuck)來抱怨你的代碼質量,而不好的代碼則更加讓人暴躁抓狂。
【標識符名稱長度】
標識符的長度包含類名、變量名、方法名等的長度。主要看以下方面
- 是否具有自描述性?不看註釋就可以理解其含義
- 是否足夠簡潔?太長的變量名降低效率
度量方式:所有標識符的平均長度。
【命名獨特性比例(UNIQ)】
當兩個實體名稱相同時,它們可能會混合在一起。 UNIQ衡量所有名字的獨特性。在許多地方使用相同的名稱是可以接受的。 然而,這個名字應該是指同樣的邏輯事物。
【代碼復雜度和代碼行數】
復雜的代碼不可能被理解。
一個方法越長,它可能越難理解。
【註釋的密度 MCOMM%】
代碼中的註釋越多,閱讀和理解越容易。
【如何編寫易於理解的代碼】
- 遵循命名規範
- 限制代碼行的最大長度、文件的最大LoC
- 足夠的註釋
- 代碼有好的布局:縮進、空行、對其、分塊、等。
- 避免多層嵌套—增加復雜度
- 文件和包的組織
代碼的可讀性/可理解性很多時候比效率/性能更重要,不可讀、不可理解代碼可能蘊含更多的錯誤。 因此先寫出可讀易懂的代碼,再去逐漸調優!
【可讀性強的語句的栗子】
Example A:z = ((3*x^2) + (4*x) - 5) - (( 2*y^2) - (7*y) + 11) / ((3*x^2) + (4*x) - 5)
Example B:a = (3*x^2) + (4*x) - 5; b = ( 2*y^2) - (7*y) + 11; z = (a - b) / a
B的代碼可讀性強於A
## 編碼規範
- 編碼規範:定義了一系列的規則,按這些規則進行編碼,有助於提升代碼可讀性,例如—— 命名、代碼布局/縮進、數據聲明方式、文件組織方式 、etc。
【命名】
- 變量,函數或類的名稱應告訴你,它為什麽存在,它做了什麽以及如何使用它。
- 如果名稱需要註釋,則名稱不必顯示意圖:
int d; // elapsed time in days int elapsedTimeInDays; int daysSinceCreation;
- 需要註意一下內容:
- 避免造假:避免留下模糊代碼含義的虛假線索。例如僅當
accountList
實現List
時才使用accountList
; 其他情況下accounts
更好。 - 做出有意義的區別
- 使用可發音名稱
- 使用可搜索的名稱
- 避免造假:避免留下模糊代碼含義的虛假線索。例如僅當
- 命名規範:
- 包名稱應該是小寫的;
- 類和接口名稱應該是名詞和大寫;
- 方法名稱應該是動詞並以小寫開始;
- 常量命名:所有大寫字母之間帶下劃線;
- 參數命名,確保你的參數意味著什麽。
【行數限制】
- 限制每一行的長度;
- 每一個方法大概三十行,在一頁內實現;
- 每一個文件大概200行,最多不超過500行。
【垂直格式化:空行】
- 單行空行
- 在局部變量聲明 和 方法中的第一個代碼之間
- 在塊註釋之前
- 在代碼的邏輯段之間提高可讀性
- 雙行空行
- 在方法之間
- 在類和接口聲明之間
- 在源文件的任何其他部分之間
- 垂直密度意味著密切關聯,因此密切相關的代碼行應該垂直密集。
- 密切相關的概念應該保持垂直相互靠近。
- 他們的垂直分離應該衡量每個人對另一個人的可理解性有多重要。
【橫向格式化:空格】
我們使用水平空白區域來關聯強烈關聯的事物,並將與強調它們的關系更加微弱的事物分開。
【橫向格式化:縮進】
代碼必須根據其嵌套級別進行縮進。你可以選擇縮進量,但應該保持一致。不好的縮進會使程序難以閱讀,也可能成為一個難以理解的錯誤來源。
【橫向格式化:換行】
當一個表達式不適合單獨一行時,根據以下一般原則將它換行:
- 逗號後換行
- 在操作符前換行
- 將新行與上一行中相同級別的表達式的開頭對齊。
【文件組織】
- 在源文件中的順序:
- 包或文件級別的註釋
- 包和導入的說明
- public的類和接口的聲明
- private的類和接口的聲明
- 導入說明的順序:
- 標準包(
java.io, java.util, etc
) - 第三方包(例如
com.ibm.xml.parser
) - 你自己的包
- 標準包(
- 類部分的順序:
- Javadoc 註釋
- 類聲明的說明
- 整個類的註釋
- 類靜態變量聲明(public,protected,package,private)
- 類實例變量聲明(public,protected,package,private)
- 函數聲明(構造函數優先)
- Principles of Package:
- 復用/發布等價原則(REP)
- 復用的粒度應等價於發布的粒度
- 共同封閉原則(CCP)
- 一個包中的所有類針對同一種變化是封閉的;
- 一個包的變化將會影響包裏所有的類,而不會影響到其他的包;
- 如果兩個類緊密耦合在一 起,即二者總是同時發生變化,那麽它們就應屬於同一個包。
- 共同復用原則(CRP)
- 一個包裏的所有類應 被一起復用;
- 如果復用了其中一個類,那麽就應復用所有的類
- 復用/發布等價原則(REP)
- Principles of Package Coupling:
- 無圈依賴原則 (ADP)
- 不允許在包依賴 圖中出現任何圈/回路;
- 無圈將容易 進行測試、維護與理解;
- 若存在回路依賴,很難預測該包的變化將會如何影響其他包。
- 消除圈的兩種方式:創建新包和利用DIP<依賴倒置原則>和ISP<接口隔離原則>。
- 創建新包
- 創建新包
- 利用DIP<依賴倒置原則>和ISP<接口隔離原則>
- 穩定依賴原則(SDP)
- 包之間的依賴關系只能指向穩定的方向;
- 被依賴者應更穩定於依賴者;
- 穩定的包較難發生改變;
- 如果不穩定的包卻被很多其他 包依賴,會導致潛在的問題。
- 穩定抽象原則(SAP)
- 在穩定性與抽象度之間建立關聯;
- 一個包是穩定的,那麽它就應該盡可能抽象;
- 一個完全穩定的包中只應包含抽象類;
- 不穩定的包應是具體的,以便於容易的進行修改。
- 無圈依賴原則 (ADP)
- SAP與SDP比較:
- SAP和SDP共同構成了包之間的“ 依賴倒置原則DIP”;
- SDP: 依賴應指向穩定的方向,SAP: 穩定性隱含著抽象;
- 因此,依賴應指向抽象的方向。
【軟件構造】第四章第一節 面向可理解性的構造