第1章 面向對象思想數據庫
第2章 抽象編程
第3章 面向對象設計設計模式
第4章 類和方法數據結構
第8章 繼承與替換模塊化
第1章 面向對象思想
第2章 抽象
第3章 面向對象設計
第4章 類和方法
第5章 消息,實例和初始化
第6章 案例研究: 八皇后問題
第7章 研究研究: 檯球遊戲
第8章 繼承與替換
第9章 案例研究: 紙牌遊戲
第10章 子類和子類型
第11章 靜態行爲和動態行爲
第12章 替換的本質
第13章 多重繼承
第14章 多態及軟件複用
第15章 重載
第16章 改寫
第17章 多態變量
第18章 泛型
第19章 容器類
第20章 案例研究: 標準模板庫
第21章 框架
第22章 框架實例: AWT和Swing
第23章 對象互連
一種考慮對象互連的方式就是研究可視性(visibility)和依賴性(dependency)這兩個概念.可視性這個軟件工程術語描述了關於名稱的特性----經過該名稱句柄能夠存取對象.若是對象的名稱是合法的且表明該對象,那麼在這個特定的環境下,該對象就是可見的.一般,用於描述可視性的相關術語還包括標識符的範疇(scope)
可視性與連通性的關係體如今: 若是咱們可以控制並下降做爲標識符的名稱的可見性,那麼就能更加容易肯定應該如何使用標識符.
依賴性這個概念將兩個對象或者類聯繫起來.在不存在另一個對象的條件下,若是一個對象的存在無任何意義,咱們就說該對象依賴於另外那個對象.例如,子類幾乎老是依賴於它的父類.
23.1 耦合和內聚
耦合(coupling)和內聚(cohesion)的思想提供了一個框架,用於評價對象和類的應用是否有效.耦合描述了類之間的關係,而聚合描述了類內部的關係.所以,若是想要下降類之間的互連性,能夠經過減小類之間的耦合來實現.另外一方面,設計良好的類應該具備特定的目的;全部元素都應該與一個任務相關.這意味着在一個良好的設計中,類內部的元素應該具備內部的內聚性
23.1.1 耦合的種類
類之間的耦合能夠有各類緣由,其中某些耦合比另一些耦合更可接受或更理想.從最差到較好的耦合以下面所示
內部數據耦合
全局數據耦合
控制(或順序)耦合
組件耦合
參數耦合
子類耦合
內部數據耦合發生在當一個類的實例直接修改另一個類中的本地數據值(實例變量)時.
class SneakyModifier { public: void sneaky() { // change my friends name myFriend->name = "Lucy"; } Person * myFriend; }; class Person { public: Person() { name = "Larry"; } string name; };
內部數據耦合這種作法很是很差的緣由在於,這種方式使得想要獨立理解類變得很是複雜.若是某個開發者只負責當前的類,那麼若是這個類的內部數據字段戲劇性地被外部的某種行爲所修改,該開發者將如何知道這一行爲呢?這種作法將使程序很是難以理解和推斷,應該儘量地避免.
全局數據耦合發生在兩個或者更多個類都依賴於公用的全局數據結構而綁定到一塊兒的時候
double todaysDow; class One { public: void setDow() { todaysDow = 9473; } }; class Two { public: void printDow() { cout << "Today the Dow hit " << todayDow; } };
一樣,這種耦合形式很差的緣由在於獨立理解類會變得很是複雜.每一個類自身都是不完整的,只有同時研究多個類定義時,纔可以理解這些類之間的相互做用.可是,全局數據耦合有時是不可避免的
在實踐中,如何區分下面這兩種全局變量很是重要.在涉及多文件的程序中,某些全局變量具備文件範疇(file scope),這意味着只能在一個文件中使用這些變量.另外一種全局變量則具備程序範疇(program scope),這意味着能夠在程序中的任何位置對其進行修改.瞭解具備程序範疇的全局變量的使用比了解具備文件範疇的全局變量的使用要困可貴多
許多語言都提供了用來在單獨類與整個程序之間控制名稱可視性的技術.這方面的實例包括C++語言中的名稱空間,Java語言中的包以及Object Pascal語言中的單元等.這些特徵支持某些名稱具備超過一個單獨類但卻小於整個程序的範疇.當對象之間經過這種數值進行交互時,程序之間發生做用的部分減小了,所以這種作法將比對象之間經過真正的全局變量進行交互的作法要更好,可是,這種耦合仍然難以理解,而且也應該儘量地避免
在面向對象框架中,可能存在的代替全局數據耦合的方法就是創建新類,整個類負責"管理"數據值,全部對全局數值的存取都需通過這個類(這種方法相似於咱們使用存取函數來屏蔽在對象內部直接存取本地數據的作法).這種技術將全局數據耦合下降到參數耦合級別上,而參數耦合更容易理解和控制.在Java語言中,不存在全局變量,全部的數值都必須經過類來管理
class MyClass { public: void mustDoFirst() { ... } void doSecond() { ... } void doThird() { ... } };
控制或者順序耦合發生在一個類必須以一種由任意位置控制的特定的順序來執行操做時.數據庫系統可能會順序經歷如下幾個步驟:執行初始化階段,讀取當前記錄,更新記錄,刪除記錄,以及產生報告等.可是,每一個階段都經過不一樣的例程來調用,而且調用順序依賴於不一樣位置上的代碼.控制耦合的存在說明類的設計者只需跟隨低級別的抽象便可(每一個步驟都對應一條指令,「處理數據庫」).即便控制耦合不可避免,一般也會謹慎地要求正被順序化的類必須確保其自身可以以正確的順序實現操做,而並不依賴於調用者的正確處理
組件耦合發生在一個類包含的數據字段或數值爲另一個類的實例時.組件耦合的這種關係是一種理想的耦合方式.容器顯然知道它所包含的數值所屬的類,可是它所包含的元素卻不該該知道關於它所處的容器的狀況
class Set { . . . private: List data; };
參數耦合發生在一個類必須調用另一個類的服務和例程時,此時兩個類之間所發生的惟一關係就是一個類須要爲另外一個類提供參數數目,類型和返回值類型.這種耦合形式很常見,容易理解,並易於驗證(例如,使用檢查參數調用與定義不匹配的工具);所以,這是一種最良好的耦合方式
class MyClass { public: void doSomething(Set aSet) { // do something using the argument value . . . } }
子類耦合是面向對象編程所特有的.它描述了一個類與其父類之間的關係.經過繼承,子類的實例能夠被當作父類的實例
class Parent { . . . } class Child extends Parent { . . . }
23.1.2 內聚的種類
類的內部內聚性是該結構之中各個元素之間綁定程度的量度.與耦合相似,從最弱的內聚(最少指望的)到最強的內聚(最指望的)依次排列的結果以下所示
隨機內聚
邏輯內聚
時間內聚
通訊內聚
順序內聚
功能內聚
數據內聚
隨機內聚發生在沒有明顯緣由而對一個類的元素進行分組時.一般這都是對一個大型程序隨意劃分紅多個部分(相似於模塊化)的結果.這每每是設計很差的一個標誌.在面向對象框架中,當類由多個無關的方法組成時,咱們就稱這種狀況爲隨機內聚
邏輯內聚發生在每一個數據或控件中,類的各個元素之間存在着邏輯的聯繫但並不存在實際的聯繫時.若是算術函數庫(正弦, 餘弦等函數)中的各個函數都在不參照其餘函數的條件下獨立實現各自的功能,那麼該函數庫就展現了一種邏輯內聚
時間內聚發生在因爲多個元素幾乎同時使用而綁定到一塊兒時.典型的例子就是用來實現程序初始化的類.這裏,更好的設計是經過不一樣的類來實現不一樣的初始化活動,使每一個類都負責更具體的後續行爲
通訊內聚發生在一個類的全部方法因爲須要存取相同的"輸入/輸出"數據或設備而組合到一塊兒時.類將扮演數據或者設備的"管理者"的角色
23.1.3 德墨特爾法則
23.1.4 類級別可視性與對象級別可視性
23.1.5 活動值
23.2 子類客戶和用戶客戶
23.3 存儲控制和可視性
23.3.1 Smalltalk語言中的可視性
23.3.2 C++語言中的可視性
23.3.3 Object Pascal語言中的可視性
23.3.4 Java語言中的可視性
23.3.5 Objective-C語言中的可視性
第24章 設計模式
第25章 反射和內省
第26章 分佈式對象
第27章 實現
參考文獻