## 第5章 軟件構建中的設計
**關于設計啟發的總結**
### 下面是對主要的設計中的啟發式方法的總結:
- 尋找現實世界的對象
- 辨別對象及其屬性(數據和方法)
- 確定可以對各個對象進行的操作
- 確定各個對象能對其他對象進行的操作
- 確定對象的那些部分是可見的.
- 形成一致的抽象
- 封裝實現細節
- 在可能的情況下繼承
- 藏住秘密(信息隱藏)
兩種秘密:
- 隱藏復雜度: 這樣就不用去應付它, 除非你要特別關注它時.
- 隱藏變化源: 當變化發生時, 器影響能限定在局部范圍內.
信息隱藏的障礙:
- 信息過度分散?
- 循環依賴?
- 把類內數據誤認為全局數據?
- 可以覺察的性能損耗?
信息隱藏的價值:
- 具有獨特的啟發力?
- 它能夠激發出有效的設計方案?
- 找出容易變化的區域
- 找出看起來容易變化的項目?
- 把容易變化的項目分離出來?
- 把看起來容易變化的項目隔離開來?
- 容易變化的區域:
- 業務規則
- 對硬件的依賴性
- 輸入和輸出
- 非標準的語言特性
- 困難的設計區域和構建區域
- 狀態變量
- 保持松散耦合
耦合的標準:規模,可見性,靈活性
### 耦合的種類:
- 簡單數據參數耦合
- 對象參數耦合
- 簡單對象耦合
- 語義上的耦合
### 語義耦合示例:
- Module1向Module2傳遞一個控制標志, 告訴Module2該做什么.這種方法要求Module1 對 Module2的內部工作細節有所了解, 也就是說需要了解Module2 對控制標志的使用, 如果 Module2 把這個標志定義成一種特定的數據類型(枚舉或對象),還過得去;
- Module2 在 Module1修改了某個全局數據之后使用該全局數據, 這種方式就要求Module2 假設Module1對該數據作出的修改符合Module2的需要.并且Module1已經在恰當地的時間調用過.
- Module1的接口要求它的Module1.initialize()子程序必須在Module1.runtime()方法之前調用. Module2知道Module1.runtime() 無論如何都會調用Module1.initialize(),所以, Module2 在實例化Module1之后并未去調用 initialize()子程序, 因為它知道調用rountime()時會調用它;
- Module1把 Object傳給Module2, 由于Module1知道Module2值用了Object的7個方法中的3個, 因此它只部分初始化Object–只包含那3個方法所需的數據;
- Module1 把BaseObject 傳給Module2, 由于Module2 知道Module1實際上只傳給它是BeviedObject, 所以它把BaseObject 強制轉換成DerivedObject, 并且調用DerivedObject 特有的方法.
記住 : 類和子程序是用于降低復雜度的首選和最重要的工具.
查閱常用的設計模式:
- 設計模式通過吧對話提升到一個更高層次來簡化交流
- 設計模式通過提升多種設計方案二帶來啟發性價值
- 設計模式通過吧常見解決方案的細節予以制度化以減少出錯.
- 探尋通用的設計模式
### 下列的啟發式方法優勢也很有用:
- 高內聚性
- 構造分層結構
- 嚴格描述類契約
- 分配職責
- 為測試而設計
- 避免失誤
- 有意識地選擇綁定時間
- 創建中央控制點
- 畫一個圖,頂一千句話
- 保持設計模塊化
### 設計中的挑戰
- 設計是一個險惡的問題.
- 設計是一個無章法的過程.即使他能看出清爽的成果.
- 設計就是確定取舍和調整順序的過程.
- 設計受到諸多限制.
- 設計是不確定的.
- 設計是一個啟發式的過程.
- 設計是自然而然形成的.
### 關鍵的設計概念
- 如今的首要技術使命:管理復雜度
- 偶然的難題和本質的難題
- 管理復雜度的重要性
- 如何應對復雜度
### 理想的設計特征
- 最小的復雜度
- 易于維護
- 松散耦合
- 可擴展性
- 可重用性
- 高扇入
- 低扇出
- 精簡性
- 層次性
- 標準技術
### 設計的層次
- 軟件系統(1層)
- 分解成為子系統
- 常用的子系統
- 業務規則
- 用戶界面
- 數據庫的訪問
- 對系統的依賴性
- 分解成類(或者包,3層)
- 分解為子程序(第4層)
- 子程序內部設計(第5層)
### 中文要點
- 軟件的首要技術使命就是管理復雜度。以簡單性作為努力目標的設計方案對此最有幫助。
- 簡單性可以通過兩種方式來獲取:一是減少在同一時間所關注的本質性復雜度的量,二是避免生成不必要的偶然的復雜度。
- 設計是一種啟發式的過程。固執于某一種單一方法會損害創新能力,從而損害你的程序。
- 好的設計都是迭代的。你嘗試設計的可能性越多,你的最終設計方案就會變得越好。
- 信息隱藏是個非常有價值的概念。通過詢問“我應該隱藏些什么?”能夠解決很多困難的設計問題。
- 很多有用有趣的、關于設計的信息存在于本書之外。這里所給出的觀點只是對這些有價值資源的一點提示而已。
### English Key Points:
- Software’s Primary Technical Imperative is managing complexity. This is accomplished primarily through a design focus on simplicity.
- Simplicity is achieved in two general ways: minimizing the amount of essential complexity that anyone’s brain has to deal with at any one time and keeping accidental complexity from proliferating needlessly.
- Design is heuristic. Dogmatic adherence to any single methodology hurts creativity and hurts your programs.
- Good design is iterative; the more design possibilities you try, the better your final design will be.
- Information hiding is a particularly valuable concept. Asking, “What should I hide?” settles many difficult design issue.
- Lots of useful, interesting information on design is available outside this book. The perspectives presented here are just the tip of the iceberg.