設計原則(7):合成(組合せ)重合多重化原則

4274 ワード

関係を継承するのではなく、オブジェクトの組合せ/集約をできるだけ使用してソフトウェアの多重化の目的を達成します.
話が多くないなら先にコードをつけなさい
  • ビジネスシーン:mysqlデータベースで製品を保存する
  • データベース接続DBConnectionを定義し、Mysqlの接続を直接返します.
    public class DBConnection1 {
        public String getConnection(){
            return "MySQL     ";
        }
    }
    

    Dao層
    public class ProductDao1 {
        public void addProduct(DBConnection1 dbConnection){
            String conn = dbConnection.getConnection();
            System.out.println("  "+conn+"    ");
        }
    }
    

    テストクラス
    public class Test1 {
        public static void main(String[] args) {
            ProductDao1 productDao = new ProductDao1();
            DBConnection1 dbConnection = new DBConnection1();
            productDao.addProduct(dbConnection);
        }
    }
    

    しゅつりょく
      MySQL         
    

    問題なく、製品は正常にmysqlを保存して、この時需要は変更して、システムの中で新しいデータベースを加入してPostgreSQLのようですまず私達は直接DBConnection 1の中で方法を増加することを思い付きます
        public String getPostgreSQLConnection(){
            return "PostgreSQL     ";
        }
    

    しかし、これは開閉の原則に違反しています.
    合成多重化の原則DBConnectionを再定義し、抽象クラスに変更
    public abstract class DBConnection2 {
        public abstract String getConnection();
    }
    

    Mysql実装を追加
    public class MySQLConnection extends DBConnection2 {
        @Override
        public String getConnection() {
            return "MySQL     ";
        }
    }
    

    DAOレイヤを書き換える
    public class ProductDao2 {
    
        private DBConnection2 dbConnection2;
    
        public void setDbConnection2(DBConnection2 dbConnection2) {
            this.dbConnection2 = dbConnection2;
        }
    
        public void addProduct(){
            String conn = dbConnection2.getConnection();
            System.out.println("  "+conn+"    ");
        }
    }
    

    テストクラス
    public class Test2 {
        public static void main(String[] args) {
            ProductDao2 productDao2 = new ProductDao2();
            productDao2.setDbConnection2(new MySQLConnection());
            productDao2.addProduct();
        }
    }
    

    この場合は変更が必要で、PostgreSQLに加入する必要があります.PostgreSQL Connectionの実装を追加するだけです.PostgreSQLConnection
    public class PostgreSQLConnection extends DBConnection2 {
        @Override
        public String getConnection() {
            return "PostgreSQL     ";
        }
    }
    

    テストクラスデータソースの変更
    public class Test2 {
        public static void main(String[] args) {
            ProductDao2 productDao2 = new ProductDao2();
            //productDao2.setDbConnection2(new MySQLConnection());
            //productDao2.addProduct();
            productDao2.setDbConnection2(new PostgreSQLConnection());
            productDao2.addProduct();
        }
    }
    

    合成多重化の原則の核心思想は,継承多重化の代わりに合成/重合多重化を用いてクラスの結合性を低下させることである.
    合成集約多重化と継承多重化の比較(なぜ合成/集約多重化が使用され、継承多重化が使用されないのか)
    オブジェクト向けの設計には、合成/集約多重化と継承多重化の2つの基本的な方法があります.両者の特徴と区別、長所と短所は以下の通りである.
    1、合成/重合多重化
    合成または集約は、既存のオブジェクトを新しいオブジェクトに組み込み、新しいオブジェクトの一部にすることができるため、新しいオブジェクトは既存のオブジェクトの機能を呼び出すことができます.このようにするメリットは
    (1)新しいオブジェクトがコンポーネントオブジェクトにアクセスする唯一の方法は,コンポーネントオブジェクトのインタフェースを通過することである.
    (2)この多重化は,成分オブジェクトの内部の詳細が新しいオブジェクトには見えないため,ブラックボックス多重化である.
    (3)この多重化はパッケージをサポートする.
    (4)このような多重化に必要な依存は少ない.
    (5)各新しいクラスは,1つのタスクに焦点を当てることができる.
    (6)この多重化は、再実行時間内に動的に行うことができ、新しいオブジェクトは、成分オブジェクトタイプと同じオブジェクトを動的に参照することができる.
    一般に、1つのロールがより多くの責任を負う場合、合成/集約関係を使用して新しい責任を適切なオブジェクトに委任できます.もちろん,この多重化にも欠点がある.最も主要な欠点は,このような多重化によって構築されたシステムがより多くのオブジェクトを管理する必要があることである.
    2、継承多重
    継承多重化は、既存のオブジェクトの実装を拡張することによって新しい機能を得、ベースクラスは共通の属性と方法を明らかにキャプチャし、サブクラスは新しい属性と方法を追加することによってスーパークラスの実装を拡張する.継承はタイプの多重化です.
    多重化の利点を継承します.
    (1)スーパークラスの大部分の機能は継承関係によって自動的にサブクラスに入ることができるため,新しい実装が容易である.
    (2)継承された実装を修正または拡張することが容易である.
    多重化された欠点を継承します.
    (1)継承多重はパッケージを破壊する.継承はスーパークラスの実装の詳細をサブクラスに暴露するからである.スーパークラスの内部の詳細はしばしばサブクラスに対して透明であるため、この多重は透明な多重であり、「ホワイトボックス」多重とも呼ばれる.
    (2)スーパークラスの実装が変更された場合、サブクラスの実装も変更せざるを得ない.したがって、1つのベースクラスが変更された場合、この変更は1つのサブクラスに伝達され、デザイナーはこれらのサブクラスを変更してスーパークラスの変化に適応しなければならない.
    (3)スーパークラスから継承された実装は静的であり,実行時間内に変化することは不可能であるため,十分な柔軟性がない.
    継承多重化には以上の欠点があるため、継承ではなく合成/集約をできるだけ使用して実現する多重化を達成することは、非常に重要な設計原則である.
    リファレンスhttps://blog.csdn.net/u010832572/article/details/45007933
    メリット
  • システムをより柔軟にする
  • githubソース