文章目錄
- 一、合成複用原則簡介
- 二、合成複用 與 繼承複用 優缺點
- 三、合成複用原則代碼示例
-
- 1、繼承複用代碼示例
- 2、合成複用代碼示例
一、合成複用原則簡介
合成複用原則 又稱為 組合複用原則 , 合成/聚合複用原則 , 組合/聚合複用原則 ;
合成複用原則定義 : 想要達到 軟體複用 的目的 , 盡量使用 對象 組合/聚合 , 而不是 繼承關系 ;
聚合 是 has-A 關系 ; ( 關系較弱 ) 代表部分事物的對象 ( 次 ) 與 代表聚合事物的對象 ( 主 ) 生命周期無關 , 删除了聚合對象 , 不代表删除了代表部分事物的對象 ;
組合 是 contains-A 關系 ; ( 關系較強 ) 一旦删除 代表組合事物的對象 ( 主 ) , 那麼 代表部分事物的對象 ( 次 ) 也一起被删除 ;
繼承 是 is-A 關系 ;
電腦 與 U 盤 是聚合關系 , 電腦沒了 , U 盤可以獨立存在 , 還可以接在其它電腦上 ;
A 類中包含了 B 類的引用 , 當 A 類對象銷毀時 , B 類引用所指向的對象也一同消失 , 沒有任何一個引用指向他 , 該引用成為了垃圾對象 , 被回收 ; 這種情況就是 組合 ;
加入 A 類銷毀後 , B 類對象還有在其它位置被引用 , B 類對象不會被銷毀 , 此時這種關系就是 聚合 ;
二、合成複用 與 繼承複用 優缺點
合成複用優點 : 使系統 更加靈活 , 降低 類與類 之間的耦合度 , 一個類的變化對其他類造成的影響相對較少 ;
合成複用缺點 : 通過 組合 / 聚合 方式建造的系統 , 有較多的對象需要管理 ;
繼承複用優點 : 擴充性容易實作 , 繼承父類後 , 父類的所有功能都可以通過繼承關系進入子類 , 修改和擴充都比較容易 ;
繼承複用缺點 : 破壞包裝 , 繼承将父類的實作細節暴露給了子類 , 這種複用稱為白箱複用 ;
繼承複用 稱為 白箱複用 , 組合 / 聚合 複用 稱為 黑箱複用 ;
黑箱複用 看不到 , 如 A 類中包含 B 類 , A 看不到 B 的具體實作細節 ;
三、合成複用原則代碼示例
1、繼承複用代碼示例
業務場景 : 向資料塊中添加資料 ; 先擷取資料庫連接配接 , 然後向資料庫中添加資料 ;
資料塊連結類 :
package compositionaggregation;
/**
* 資料塊連接配接
*/
public class DBConnection {
public String getConnection() {
return "資料連接配接";
}
}
增加資料類 :
package compositionaggregation;
/**
* 創造産品
*/
public class ProductDao extends DBConnection {
/**
* 增加産品
*/
public void addProduct() {
// 先擷取連接配接
String conn = super.getConnection();
System.out.println("使用 " + conn + " 增加産品");
}
}
測試類 :
package compositionaggregation;
public class Main {
public static void main(String[] args) {
ProductDao productDao = new ProductDao();
productDao.addProduct();
}
}
執行結果 :
2、合成複用代碼示例
資料庫連接配接抽象類 :
package compositionaggregation;
/**
* 資料塊連接配接
*/
public abstract class DBConnection {
public abstract String getConnection();
}
Oracle 資料庫連接配接類 :
package compositionaggregation;
/**
* Oracle 資料塊連接配接
*/
public class OracleConnection extends DBConnection {
@Override
public String getConnection() {
return "Oracle 資料庫連接配接";
}
}
MySQL 資料庫連接配接類 :
package compositionaggregation;
/**
* MySQL 資料塊連接配接
*/
public class MySqlConnection extends DBConnection {
@Override
public String getConnection() {
return "MySQL 資料庫連接配接";
}
}
插入資料類 : 通過組合複用 , 注入資料庫連接配接類 ;
package compositionaggregation;
/**
* 創造産品
*/
public class ProductDao {
/**
* 通過組合方式注入資料庫連接配接
*/
private DBConnection connection;
public ProductDao(DBConnection connection) {
this.connection = connection;
}
/**
* 增加産品
*/
public void addProduct() {
// 先擷取連接配接
String conn = connection.getConnection();
System.out.println("使用 " + conn + " 增加産品");
}
}
package compositionaggregation;
public class Main {
public static void main(String[] args) {
ProductDao productDao = new ProductDao(new OracleConnection());
productDao.addProduct();
}
}