デザインパターン---複合パターン

1はじめに

Wordの編集では、単語を編集する必要がある場合と、テキストの一部を編集する必要がある場合があります。単語または単語の行の編集動作は同じです。抽象化はパーツ全体の関係であり、対応するのは組み合わせデザインパターンです。

2定義

全体部分パターンと呼ばれることもある構成デザインパターンは、オブジェクトをツリーのような階層に構成して「全体部分」の関係を表現するためのパターンであり、ユーザーは複合オブジェクトと同じ操作性とアクセス性を備えています。構造デザインパターンに属します。

組み合わせモードは、一般的に全体と部分の関係を表すために使用され、オブジェクトをツリー構造に編成します。最上位ノードはルートノードと呼ばれます。ルートノードには、ブランチノードとリーフノード、およびブランチを含めることができます。ノードには、ブランチノードとリーフノードを含めることができます。

3構造と実装

構成モードの構造と実装は複雑ではありません。主な役割は抽象構造(コンポーネント)の役割であり、次にリーフ(リーフ)の役割とブランチ(複合)のコンポーネントの役割が続きます。

  1. 抽象コンポーネント(コンポーネント)の役割:その主な役割は、リーフおよびブランチコンポーネントのパブリックインターフェイスを宣言し、それらのデフォルトの動作を実装することです。トランスペアレントコンポジションモードでは、抽象コンポーネントはサブクラスにアクセスして管理するためのインターフェイスも宣言します。セーフコンポジションモードでは、サブクラスにアクセスして管理するためのインターフェイスは宣言されず、管理作業はブランチコンポーネントによって行われます。(一般的な抽象クラスまたはインターフェース、追加、削除などのいくつかの一般的なメソッドを定義します)
  2. リーフコンポーネント(リーフ)の役割:コンポジション内のリーフノードオブジェクトであり、子ノードはなく、抽象コンポーネントを継承または実装するために使用されます。
  3. 複合ロール/中間コンポーネント:コンポジション内のブランチノードオブジェクトであり、抽象コンポーネントを継承および実装するための子ノードがあります。その主な機能は、通常Add()、Remove()、GetChild()およびその他のメソッドを含む子コンポーネントを格納および管理することです。

抽象コンポーネントの役割は、透過モードとセーフモードに分けられます。

透過モードでは、抽象コンポーネントはすべてのサブクラスのすべてのメソッドを宣言するため、クライアントはリーフオブジェクトとブランチオブジェクトを区別する必要がなく、クライアントに対して透過的です。ただし、その欠点は、リーフコンポーネントにAdd()、Remove()、およびGetChild()メソッドがないことですが、それらを実装する必要があり(空の実装または例外をスロー)、セキュリティ上の問題が発生します。引用からの画像2。

 セキュリティモードでは、サブコンポーネントの管理方法がブランチコンポーネントに移動します。抽象コンポーネントとリーフコンポーネントにはサブオブジェクトの管理方法がないため、前の方法のセキュリティ問題を回避できます。リーフとブランチのインターフェイスは異なるため、クライアントは呼び出し時にリーフオブジェクトとブランチオブジェクトの存在を知る必要があるため、透明性が失われます。引用からの画像2。

4長所と短所

主な利点は次のとおりです。

  1. 構成モードを使用すると、クライアントコードは、単一オブジェクトを処理するか複合オブジェクトを処理するかに関係なく、単一オブジェクトと複合オブジェクトを一貫して処理できます。これにより、クライアントコードが簡素化されます。
  2. コンポジション本体に新しいオブジェクトを追加する方が簡単であり、「オープンクローズの原則」を満たす新しいオブジェクトを追加するために、クライアントがソースコードを変更することはありません。

その主な欠点は次のとおりです。

  1. 設計はより複雑であり、クライアントはクラス間の階層関係を明確にするためにより多くの時間を費やす必要があります。
  2. コンポーネントをコンテナに閉じ込めるのは簡単ではありません。
  3. 継承を使用してコンポーネントに新しい機能を追加するのは簡単ではありません。

5見積もりシナリオ

1.オブジェクトの全体と一部の階層を表す必要がある場合。

2.結合オブジェクトと単一オブジェクトの違いをユーザーから隠す必要があり、ユーザーは結合構造内のすべてのオブジェクトを統一されたインターフェースで使用できます。

6コード例

現在のユニットを例にとると、次の図に示すように、モデルが抽象化されます。

6.1会社の抽象インターフェース会社

public interface Company {

    /**
     * 获取公司名称
     * @return 名称
     */
    String getName();

    /**
     * 添加
     * @param c 公司
     */
    void add(Company c);

    /**
     * 移除
     * @param c 公司
     */
    void remove(Company c);

    /**
     * 显示
     * @param depth 层级
     */
    void disPlay(int depth);

    /**
     * 展示职责
     */
    void displayDuty();
}

6.2コンクリート会社

public class ConcreteCompany implements Company{
    private final List<Company> children = new ArrayList<>();

    private final String name;
    public ConcreteCompany(String name){
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void add(Company c) {
        children.add(c);
    }

    @Override
    public void remove(Company c) {
        children.remove(c);
    }

    @Override
    public void disPlay(int depth) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(sb.toString() + getName());
        for (Company c: children) {
            c.disPlay(depth + 2);
        }
    }

    @Override
    public void displayDuty() {
        for (Company c: children) {
            c.displayDuty();
        }
    }
}

6.3人材部門HumanResourceDepartment

public class HumanResourceDepartment implements Company{

    private String name;
    public HumanResourceDepartment(String name){
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void add(Company c) {

    }

    @Override
    public void remove(Company c) {

    }

    @Override
    public void disPlay(int depth) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(sb.toString() + getName());
    }

    @Override
    public void displayDuty() {
        System.out.println(MessageFormat.format("{0}负责管理公司人事所有事务", name));
    }
}

6.4財務部

public class FinanceDepartment implements Company {

    private String name;
    public FinanceDepartment(String name){
        this.name = name;
    }
    @Override
    public String getName() {
        return name;
    }

    @Override
    public void add(Company c) {

    }

    @Override
    public void remove(Company c) {

    }

    @Override
    public void disPlay(int depth) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(sb.toString() + getName());
    }

    @Override
    public void displayDuty() {
        System.out.println(MessageFormat.format("{0}负责管理公司财务所有事务", name));
    }
}

6.5主な機能

public class Main {
    public static void main(String[] args) {
        //海南分院
        ConcreteCompany haiNanBranch = new ConcreteCompany("海南分院");
        haiNanBranch.add(new HumanResourceDepartment("海南分院人事处"));
        haiNanBranch.add(new FinanceDepartment("海南分院财务处"));

        //云南分院
        ConcreteCompany yunNanBranch = new ConcreteCompany("云南分院");
        yunNanBranch.add(new HumanResourceDepartment("云南分院人事处"));
        yunNanBranch.add(new FinanceDepartment("云南分院财务处"));

        //总院
        ConcreteCompany institute = new ConcreteCompany("天津总院");
        institute.add(new HumanResourceDepartment("总院人力资源部"));
        institute.add(new FinanceDepartment("总院资产财务部"));
        institute.add(haiNanBranch);
        institute.add(yunNanBranch);

        System.out.println("结构图:");
        institute.disPlay(0);
        System.out.println("\n职责:");
        institute.displayDuty();
    }
}

6.6実行結果

7引用

1.「Dahuaデザインパターン」  

2.コンビネーションモード(詳細版)

8ソースコード

design-pattern-learning / src / com / hz / design / pattern / compose at main・airhonor / design-pattern-learning・GitHub

おすすめ

転載: blog.csdn.net/honor_zhang/article/details/120885117