子程式是具有一定功能的,可以調用的函數或過程;而子產品則是指資料及作用于資料的子程式的集合。
6.1 子產品化:内聚性與耦合性
“子產品化”同時涉及到子程式設計和子產品設計;子產品化設計的目标是使每個子程式都成為一個“黑盒子”;使用單獨一個子程式是很難達到這一目的的,這也正是引入子產品的原因。
6.1.1 子產品内聚性
子產品的内聚性準則,與單個子程式的内聚性準則一樣,都是十分簡單的;一個子產品應該提供一組互相聯系的服務。
6.1.2 子產品耦合
子產品與程式其它部分間的耦合标準與子程式間的耦合标準也是類似的;子產品應被設計成可以提供一整套功能,以便程式的其它部分與它清楚地互相作用。
如果子產品所提供的功能是不完善的,其它子程式可能被迫對其内部資料進行讀寫操作。
為了設計出強内聚而又松散耦合的子產品,必須在設計子產品和設計單個子程式的标準之間進行平衡與折衷;降低子程式之間耦合性的重要措施之一,就是盡可能減少使用全局變量。
從所有子產品中的子程式可以對它進行存取的角度來說,子產品中資料很像是全局資料。
6.2 資訊隐蔽
進行資訊隐蔽的設計思想貫穿了軟體開發的每一個層次,從使用命名的常量而不是使用自由常量到子程式設計、子產品設計和整個程式設計。
6.2.1 保密
資訊隐蔽中的關鍵概念是“保密”,每一個子產品的最大特點都是通過設計和實作,使它對其它子產品保密;子產品的作用是将自己的資訊隐蔽起來以保衛自己的隐私權;資訊隐蔽的另一個稱謂是“封裝”,其意思是一個外表與内容不一樣的盒子。
子產品的接口應該盡可能少地暴露它的内部内容。
6.2.2 資訊隐蔽舉例
除了友善修改,隐含複雜資料結構細節的另一個重要原因是:隐含細節可以澄清你編寫某段代碼的意圖。
隐含資料結構的最後一個原因是出于對可靠性的考慮。
隐含資料結構細節的另一個好處是容易調試。
應用存取子程式最後一個優點是,可以使所有對資料的存取所遵循的是一種平行的組織形式;或者通過存取子程式、或者直接對資料進行存取,不會兩者兼而有之。
6.2.3 常見需要隐含的資訊
容易被改動的區域:在為應付改動的工作中要遵循的步驟:1)識别出那些可能被改動的地方;2)把可能被改動的地方分離出來;一些可能變動的區域:1)對硬體有依賴的地方;2)輸入和輸出;3)非标準語言特性;4)難于設計和實作的域;5)狀态變量;6)資料規模限制;7)商業規則;8)預防到改動。
複雜的資料:所有的複雜資料都很可能被改動;如果它很複雜而對它使用得又很多,那麼在實作層次上與其打過交道後,可能會發現實作它的更好方式;對複雜資料的使用程度,主要取決于程式。
複雜的邏輯:隐含複雜的邏輯可以改善程式的可讀性。
在程式語言層次上的操作:一般來說,在設計一組在程式語言語句層次上操作資料的子程式時,應該把對資料操作隐含在子程式組中,這樣程式的其餘部分就可能在比較抽象的層次上處理問題了。
6.2.4 資訊隐蔽的障礙
資訊過度分散:資訊隐蔽的一個常見障礙是系統中資訊過于分散;另一個資訊過于分散的例子是程式中分布着與使用者互動的接口;而還有一個例子則是全局資料結構。
交叉依賴:一個不易察覺的資訊隐蔽障礙是交叉依賴。
誤把子產品資料當成全局資料:全局資料主要會産生兩個問題:1)一個子程式在對其進行操作時并不知道其它子程式也在對它進行操作;2)這個子程式知道其它子程式也在對其進行操作,但不知道它們對它幹了什麼。
誤認為會損失性能:資訊隐蔽的最後一個障礙是在結構設計和編碼兩個層次上,都試圖避免性能損失。
6.3 建立子產品的理由
一些适合使用子產品的域:1)使用者接口;2)對硬體有依賴的區域;3)輸入與輸出;4)作業系統依賴部分;5)資料管理;6)真實目标與抽象資料類型;7)可再使用的代碼;8)可能發生變動的互相聯系的操作;9)互相聯系的操作。
6.4 任何語言中實作子產品
6.4.1 子產品化所需的語言支援
子產品包括資料、資料類型、資料操作以及公共和局部操作的區分等。
資料需要在三個層次上可以被存取和隐含:在局部,在子產品中及在全局中;絕大多數語言都支援局部資料和全局資料。
對于資料類型的可存取性和可隐含性的要求,與對資料的要求是類似的。
對子產品層次上的子程式的要求也與上述相類似。
6.4.2 語言支援概述
6.4.3 僞子產品化
把資料和子程式裝入子產品;保證子產品的内部子程式是專用的;通過在說明的地方加注釋來明确區分公用和專用子程式;不允許子程式調用其它子產品的内部子程式;采用命名約定來表明一個子程式是内部的還是外部的;采用表明它是内部的還是外部的命名規定;保證子程式的内部資料是專用的。
6.4.4 檢查表
子產品的品質。
6.5 小結
(1) 不管調用哪一個,子程式與子產品的不同是很重要的,要認真考慮子程式與子產品的設計。
(2) 從子產品資料是被幾個子程式使用的這一角度來說,它與全局資料是相同的,但從可以使用它的子程式是有限的,而且清楚地知道是哪些子程式可以使用它這一角度來說,子產品資料與全局資料又是不同的;是以,可以使用子產品資料而沒有全局資料的危險。
(3) 資訊隐蔽總是有益的,其結果是可以産生可靠的易于改進的系統,它也是目前流行的設計方法的核心。
(4) 建立子產品的原因有許多是與建立子程式相同的,但子產品概念的意義要比子程式深遠得多,因為它可以提供一整套而不是單獨一個功能,是以,它是比子程式更高層次的設計工具。
(5) 可以在任何語言中進行子產品設計,如果所采用的語言不直接支援子產品,可以用程式設計約定對其加以擴充,以達到某種程度的子產品化。
本章小結:
本章介紹了子產品化設計,與上一章的子程式相對應。
在實際的項目中,子產品化的方法用得非常多。每一個開發人員所做的工作,其實就是完成了自己負責的一個子產品。在開發工作完成之後,需要進行內建測試,也就是驗證子產品之間能否協同工作。