高內聚、低耦合是軟件設計中非常關鍵的概念,但解釋起來並不那么容易。
我的解釋,可以概括為兩個基本原則:層次一致的抽象,以及相互獨立的封裝。
層次一致的抽象
在Web工程中,我們非常熟悉的是三層架構:展示層、業務層和持久層。
層次一致和不一致的抽象就像這樣:

如果業務層包含了持久層的代碼,或者持久的的代碼放到了展示層,這便是破壞了代碼的抽象層次。
同樣的:
如果工具類包含了業務方法成員或字段,這就破壞了類的抽象;
如果查詢方法包含了排序算法,這就破壞了方法的抽象;
...
抽象層次也可以更加的往上:
如果在業務服務里,部署了分布式緩存服務,這就破壞了服務的抽象。
如果負載集群里包含的業務集群,這就破壞了集群的抽象。
也就是,系統應該體現出良好的層次性,盡可能不出現跨層次調用,並保證同一層的元素是同一抽象層次。
這里舉個方法的抽象層次的例子:
public Foo(){
initServer();
}
private void initServer() {
// do something
initClient();
}
private void initClient() {
// do something
}
其中,initServer,initClient兩方法從邏輯上講應該是同一抽象層次,所以讓initServer去執行initClient是不恰當的。
恰當的抽象如下,讓更上層的構造函數執行initClient。
public Foo(){
initServer();
initClient();
}
private void initServer() {
// do something
}
private void initClient() {
// do something
}
相互獨立的封裝
那么如何更好的實現抽象,以保證高內聚、低耦合呢?
第二個原則是相互獨立的封裝。
相互獨立的封裝和相互不獨立的封裝就像這樣:

相互獨立,更通俗的點講就是一個類、一個方法只做一件事情。
它有兩層含義。
首先是與外部的相互獨立,比如,類與類之間要邏輯獨立,僅通過少量接口實現交互。如果類本身的字段使用得不多,反而過多的使用了另一個類的字段,那么就要考慮是不是要重新封裝兩個類。
其次是內部的獨立性,類應該是一個對象的抽象,貓類不能帶上狗尾巴;一個方法最好只包含一份職責,不要即控制流程,又處理業務。
層次一致的抽象,相互獨立的封裝,做到這兩點,讓程序在垂直方向上層次分明,在水平方向上相互獨立,這就是理想中高內聚、低耦合的軟件架構。
作者
- 作者:初開
- 我的開發者之道:http://dev.chukai.pro
