## 第7章:高質量的子程序
### 創建子程序的理由
- 降低復雜度
- 引入中間的、易懂的抽象
- 避免代碼重復
- 支持子類化
- 隱藏順序
- 隱藏指針操作
- 提高可移植性
- 簡化復雜的邏輯判斷
- 改善性能
### 除此之外,創建類的很多理由也是創建子程序的理由
- 隔離復雜度
- 隱藏實現細節
- 限制變化所帶來的影響
- 隱藏全局數據
- 形成中央控制點
- 促成可復用的代碼
- 達到特定的重構目的
### 在子程序層上設計:功能上的內聚性
- 順序上的內聚性
- 通信上的內聚性
- 臨時的內聚性
- 過程上的內聚性
- 邏輯上的內聚性
### 好的子程序的名字
- 描述子程序所做的所有事情
- 避免使用無意義的、模糊或表示不清的動詞
- 不要僅通過數字來形成不同的子程序名字
- 根據需要確定子程序的名字的長度
- 給函數命名時要對返回值有所描述
- 給過程起名時要使用語氣強烈的動詞加賓語的形式
- 準確使用對仗詞
```java
add/remove increment/decrement open/close
begin/end insert/delete show/hide
create/destory lock/unlock source/target
first/last min/max start/stop
get/put next/previous up/down
get/set old/new attack/detach
initial/done ensureCapacity dispose
current / past
new/create/construct/generate
update/refresh/alter/modify
get/find/load/obtain
open/draw/display/show/mark
process/execute/handle/dispose/deal
base on / depend on / convert to / transfer to
retrieve(判斷) / indicate(表明,證明)
```
### 過程命名注意:
- 一個具有功能內聚性的過程通常是指對一個對象執行一種操作.
- 過程的名字應該能夠反映出該過程所做的事.
- 你不用再過程中加入對象的名字(賓語).
- 常用的操作確立命名規則
### 7.5 如何使用子程序的參數
- 按照輸入-修改-輸出的順序排列參數
- 考慮自己創建in和out關鍵字
- 如果幾個子程序都用了類似的一些參數,應該讓這些參數的排列順序保持一致:因為子程序的參數順序可以產生記憶效應.
- 使用所有的參數
- 把狀態或出錯變量放到最后
- 不要把子程序的參數用到工作變量
- 在接口中隊參數的假定加以說明
- 把子程序的參數個數限制在大約7個以內
- 考慮對參數采用某種表示輸入、修改、輸出的命名規則
- 為子程序傳遞用以維持其接口抽象的變量或對象
- 使用具名參數
- 確保實際參數與形式參數相匹配
> checklist For High-Quality Routines
### 核對表:高質量的子程序
-------
### 大局事項
- 創建的子程序的理由充分嗎?
- 一個子程序中所有適于單獨提出的部分是不是已經被提出到單獨的子程序中了?
- 過程的名字是否用了強烈、清晰的“動詞+賓語”詞組?函數的名字是否描述了其返回值?
- 子程序的名字是否描述了它所做的全部事情?
- 是否給常用的操作建立了命名規則?
- 子程序是否具有強烈的功能上的內聚性?即它是否做且只做一件事,并且把它做好?
- 子程序之間是否有較松的耦合?子程序與其他子程序之間的連接是否是小的,明確的,可見的和靈活的?
- 子程序的長度是否是有其功能和邏輯自然確定,而非遵循任何人為的編碼標準?
### 參數傳遞事宜
- 整體來看,子程序的參數是否表現出一種具有整體性且一致的接口抽象?
- 子程序參數的排列順序是否合理?是否與類似的子程序的參數排列順序相符?
- 接口假定是否已在文檔中說明?
- 子程序的參數個數是否沒有超過7個?
- 是否用到了每一個輸入參數?
- 是否用到了每一個輸入參數?
- 子程序是否避免了吧輸入參數用做工作變量?
- 如果子程序是一個函數,那么它是否在所有可能的情況下都能夠返回一個合法的值?
### 中文要點:
- 創建子程序最主要的目的是提高程序的可管理性,當然也有其他一些好的理由。其中,節省代空間只是一個次要原因:提高可讀性、可靠性和可修改性等原因都更重要一些。
- 有時候,把一些簡單的操作寫成獨立的子程序也非常有價值。
- 子程序可以按照其內聚性分為很多類,而你應該讓大多數程序具有功能上的內聚性,這是最佳的一種內聚性。
- 子程序的名字是它的質量的指示器。如果名字糟糕但恰如其分,那就說明這個子程序設計得很差勁。如果名字糟糕而且又不準確,那么它就反映不出程序是干什么的。不管怎樣,糟糕的名字都意味著程序需要修改。
- 只有在某個子程序的主要目的是返回由其名字所描述的特定結果時,才應該使用函數。
- 細心的程序員會非常謹慎地使用宏,而且只在萬不得已時才用。
### English Key Points:
- The most important reason to create a routine is to improve the intellectual manageability of a program, and you can create a routine for many other good reasons. Saving space is a minor reason;
- improved readability, reliability, and modifiability are better reasons.
- Sometimes the operation that most benefits from being put into a routine of its own is a simple one.
- The name of a routine is an indication of its quality. If the name is bad and it’s accurate, the routine might be poorly designed. If the name is bad and it’s inaccurate, it’s not telling you what the program does. Either way, a bad name means that the program needs to be changed.
- Functions should be used only when the primary purpose of the function is to return the specific value described by the function’s name.
- Careful programmers use macro routines and inline routines with care, and only as a last resort.