Javaのコンポジットデザインパターン

1前書き

このクイックチュートリアルでは、コンポジットデザインパターンをJavaで紹介します。

構造とその使用目的について説明します。

2構造

  • 複合パターンとは、個々のオブジェクトおよびオブジェクトの構成、つまり「コンポジット」を同じ方法で処理できるようにすることを意味します。 **

基本型を継承する型からなるツリー構造と見なすことができ、オブジェクトの単一部分または全体の階層を表すことができます。

パターンを次のように分割できます。

  • component - 内のすべてのオブジェクトの基本インターフェース

組成。それは、子コンポジットを管理するための共通メソッドを持つインターフェースまたは抽象クラスのいずれかであるべきです。

  • leaf - 基本コンポーネントのデフォルトの振る舞いを実装します。それ

他のオブジェクトへの参照は含まれていません。

  • composite - リーフ要素を持ちます。基本コンポーネントを実装します

子に関連する操作をメソッドおよび定義します。

  • client - ベースを使って構成要素にアクセスする

コンポーネントオブジェクト

3実用例

それでは、実装に飛び込みましょう。会社の部署の階層構造を構築したいとしましょう。

** 3.1. 基本コンポーネント

コンポーネントオブジェクトとして、単純な Department インターフェースを定義します。

public interface Department {
    void printDepartmentName();
}

3.2. 葉

リーフコンポーネントについて、財務部門と営業部門のクラスを定義しましょう。

public class FinancialDepartment implements Department {

    private Integer id;
    private String name;

    public void printDepartmentName() {
        System.out.println(getClass().getSimpleName());
    }

   //standard constructor, getters, setters
}

2番目のリーフクラス SalesDepartment、 は似ています。

public class SalesDepartment implements Department {

    private Integer id;
    private String name;

    public void printDepartmentName() {
        System.out.println(getClass().getSimpleName());
    }

   //standard constructor, getters, setters
}

どちらのクラスも、ベースコンポーネントから printDepartmentName() メソッドを実装し、それぞれのクラス名を出力します。

また、それらはリーフクラスなので、他の Department オブジェクトを含んでいません。

次に、複合クラスも見てみましょう。

3.3. コンポジットエレメント

複合クラスとして、 HeadDepartment クラスを作成しましょう。

public class HeadDepartment implements Department {
    private Integer id;
    private String name;

    private List<Department> childDepartments;

    public HeadDepartment(Integer id, String name) {
        this.id = id;
        this.name = name;
        this.childDepartments = new ArrayList<>();
    }

    public void printDepartmentName() {
        childDepartments.forEach(Department::printDepartmentName);
    }

    public void addDepartment(Department department) {
        childDepartments.add(department);
    }

    public void removeDepartment(Department department) {
        childDepartments.remove(department);
    }
}
  • これは Department コンポーネントのコレクション** 、およびリストへの要素の追加と削除のためのメソッドを保持しているので複合クラスです。

複合 printDepartmentName() メソッドは、リーフ要素のリストを繰り返し処理し、それぞれに適切なメソッドを呼び出すことによって実装されます。

4テスト中

テスト目的で、 CompositeDemo クラスを見てみましょう。

public class CompositeDemo {
    public static void main(String args[]) {
        Department salesDepartment = new SalesDepartment(
          1, "Sales department");
        Department financialDepartment = new FinancialDepartment(
          2, "Financial department");

        HeadDepartment headDepartment = new HeadDepartment(
          3, "Head department");

        headDepartment.addDepartment(salesDepartment);
        headDepartment.addDepartment(financialDepartment);

        headDepartment.printDepartmentName();
    }
}

まず、財務部門と営業部門の2つのインスタンスを作成します。

その後、ヘッド部門をインスタンス化し、それまでに作成したインスタンスを追加します。

最後に、 printDepartmentName() 合成メソッドをテストできます。予想どおり、出力には各リーフコンポーネントのクラス名が含まれます。

SalesDepartment
FinancialDepartment

5結論

この記事では、コンポジット設計パターンについて学びました。この記事は、主な構造を強調し、実用的な例を通して使用法を示しています。

いつものように、完全なコードはhttps://github.com/eugenp/tutorials/tree/master/patterns/design-patterns[Githubプロジェクト]にあります。