組み合わせパターンのデザインパターンを再学習する

コンテンツ

  • 意味
  • 使用するシーン
  • コード

意味

複合モードは、部分全体モードとも呼ばれ、オブジェクトをツリーのような構造に結合して「部分全体」の階層を表すため、ユーザーは単一合計オブジェクトと複合オブジェクトを一貫して使用できます。組み合わせモードでは、類似性のあるオブジェクトのグループを1つのオブジェクトとして組み合わせることができます。

使用するシーン

  1. オブジェクトの部分全体の構造を表す必要がある場合。
  2. 単純な要素と複雑な要素は同じ方法で処理されます。
  3. モジュールまたは機能の一部を全体から分離することができます。

実現する方法

  1. アプリケーションのコアモデルをツリー構造で表現できることを確認してください。単純な要素とコンテナーに分解してみてください。コンテナーには、単純な要素と他のコンテナーの両方を含めることができる必要があります。
  2. 単純な要素と複雑な要素の両方に意味のあるコンポーネントインターフェイスとそのメソッドのセットを宣言します。
  3. 単純な要素を表すリーフノードクラスを作成します。プログラムには、複数の異なるリーフノードクラスが存在する可能性があります。
  4. 複雑な要素を表すコンテナクラスを作成します。このクラスでは、子要素への参照を格納する配列メンバー変数を作成します。配列はリーフノードとコンテナの両方を保持できる必要があるため、必ず複合インターフェイスタイプとして宣言してください。コンポーネントインターフェイスメソッドを実装する場合、コンテナはほとんどの作業を子に任せる必要があります。
  5. 最後に、コンテナ内の子要素を追加および削除するためのメソッドを定義します。これらの操作は、コンポーネントインターフェイスで宣言できます。リーフノードクラスのこれらのメソッドは空であるため、これはインターフェイス分離の原則に違反します。ただし、これにより、クライアントは、ツリー構造を構成する要素も含めて、すべての要素に無差別にアクセスできます。

コード

public abstract class Component {

    // 节点名
    protected String name;

    public Component(String name) {
        this.name = name;
    }

    /**
     * 具体逻辑,由子方法实现
     */
    public abstract void doSomething();

    /**
     * 添加子节点
     *
     * @param child 子节点
     */
    public abstract void addChild(Component child);

    /**
     * 移除子节点
     *
     * @param child 子节点
     */
    public abstract void removeChild(Component child);

    /**
     * 获取子节点
     *
     * @param index 下标
     * @return 子节点
     */
    public abstract Component getChildren(int index);
}

public class Composite extends Component {

    /**
     * 存储子节点的容器
     */
    private List<Component> childs = new ArrayList<Component>();

    public Composite(String name) {
        super(name);
    }

    @Override
    public void doSomething() {
        System.out.println(name);
        for (Component child : childs) {
            child.doSomething();
        }
    }

    @Override
    public void addChild(Component child) {
        childs.add(child);
    }

    @Override
    public void removeChild(Component child) {
        child.removeChild(child);
    }

    @Override
    public Component getChildren(int index) {
        return childs.get(index);
    }
}

public class ChildComposite extends Component {

    /**
     * 存储子节点的容器
     */
    private List<Component> childs = new ArrayList<Component>();

    public ChildComposite(String name) {
        super(name);
    }

    @Override
    public void doSomething() {
        System.out.println(name);
        for (Component child : childs) {
            child.doSomething();
        }
    }

    @Override
    public void addChild(Component child) {
        childs.add(child);
    }

    @Override
    public void removeChild(Component child) {
        child.removeChild(child);
    }

    @Override
    public Component getChildren(int index) {
        return childs.get(index);
    }
}

public class Leaf extends Component {

    public Leaf(String name) {
        super(name);
    }

    @Override
    public void doSomething() {
        System.out.println(name);
    }

    @Override
    public void addChild(Component child) {
        throw new UnsupportedOperationException("也子节点没有子节点");
    }

    @Override
    public void removeChild(Component child) {
        throw new UnsupportedOperationException("也子节点没有子节点");
    }

    @Override
    public Component getChildren(int index) {
        throw new UnsupportedOperationException("也子节点没有子节点");
    }
}

public class CompositeTest {

    @Test
    public void test() {
        Composite composite = new Composite("Root");
        ChildComposite childComposite = new ChildComposite("Child Root");
        Leaf branch1 = new Leaf("Branch1");
        Leaf branch2 = new Leaf("Branch2");
        Leaf branch3 = new Leaf("Branch3");
        childComposite.addChild(branch3);
        composite.addChild(branch1);
        composite.addChild(branch2);
        composite.addChild(childComposite);
        composite.doSomething();
    }
}

Root
Branch1
Branch2
Child Root
Branch3
复制代码

おすすめ

転載: juejin.im/post/6956243329239498760