天天看點

【設計模式】軟體設計七大原則 ( 合成複用原則 | 代碼示例 )

文章目錄

  • 一、合成複用原則簡介
  • 二、合成複用 與 繼承複用 優缺點
  • 三、合成複用原則代碼示例
    • 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();
    }
}
           

繼續閱讀