## 一、定義
合成/聚合復用原則是**在一個新的對象里面使用一些已有的對象,使之成為新對象的一部分;新的對象通過向這些對象的委派達到復用已有功能的目的**。
簡述為:**要盡量使用合成/聚合,盡量不要使用繼承**。
## 二、具體說明
>繼承我們叫做白箱復用,相當于把所有的實現細節暴露給子類。組合/聚合稱為黑箱復用,我們是無法獲取到類以外的對象的實現細節的。雖然我們要根據具體的業務場景來做代碼設計,但也需要遵循 OOP 模型。以數據庫操作為例,先來創建 DBConnection 類:
~~~
public class DBConnection {
public String getConnection() {
return "MySQL 數據庫連接";
}
}
~~~
創建 ProductDao 類:
~~~
public class ProductDao {
private DBConnection dbConnection;
public void setDbConnection(DBConnection dbConnection) {
this.dbConnection = dbConnection;
}
public void addProduct() {
String conn = dbConnection.getConnection();
System.out.println("使用" + conn + "增加產品");
}
}
~~~
這就是一種非常典型的合成復用原則的應用場景。但是,就目前的設計來說,DBConnection 還不是一種抽象,不便于系統擴展。目前的系統支持 MySQL 數據庫連接,假設業務發生變化,數據庫操作層要支持 Oracle 數據庫。當然,我們可以在 DBConnection 中增加對 Oracle 數據庫支持的方法。但是這違背了開閉原則。其實,我們可以不必修改 Dao 的代碼,將 DBConnection 修改為 abstract,來看代碼:
~~~
public abstract class DBConnection {
public abstract String getConnection();
}
~~~
然后,將 MySQL 的邏輯抽離:
~~~
public class MySQLConnection extends DBConnection {
@Override
public String getConnection() {
return "MySQL 數據庫連接";
}
}
~~~
再創建 Oracle 支持的邏輯:
~~~
public class OracleConnection extends DBConnection {
@Override
public String getConnection() {
return "Oracle 數據庫連接";
}
}
~~~
具體選擇交給應用層,來看一下類圖:

- 前言
- 第一章 設計七大原則
- 第1節 開閉原則
- 第2節 依賴倒置原則
- 第3節 單一職責原則
- 第4節 接口隔離原則
- 第5節 迪米特法則
- 第6節 里氏替換原則
- 第7節 合成復用原則
- 第二章 簡單工廠模式
- 第1節 使用場景
- 第2節 示例代碼
- 第三章 創建者模式
- 第1節 工廠方法模式
- 第2節 抽象工廠模式
- 第3節 建造者模式
- 第4節 原型模式
- 第5節 單例模式
- 第四章 結構型模式
- 第1節 適配器模式
- 第2節 橋接模式
- 第3節 組合模式
- 第4節 裝飾者模式
- 第5節 外觀模式
- 第6節 享元模式
- 第7節 代理模式
- 第五章 行為模式
- 第1節 責任鏈模式
- 第2節 命令模式
- 第3節 迭代器模式
- 第4節 中介者模式
- 第5節 備忘錄模式
- 第6節 觀察者模式
- 第7節 狀態模式
- 第8節 策略模式
- 第9節 模板方法模式
- 第10節 訪問者模式
- 第11節 解釋器模式