読者です 読者をやめる 読者になる 読者になる

【デザインパターン】Composite

どんなもの

  • Compositeとは複合物を意味する言葉。
  • オブジェクトを木構造として階層全体を表現する
  • 容器と中身を同一視する("Directories contain entries, each of which could be a directory")ことで、再帰的な構造の取り扱いを容易にする。

どんなときに使う?

  • 容器なのか中身なのかを意識せずに、同じ操作をしたいとき

典型的な構成要素

  • Component
    • LeafとCompositeの抽象クラス
  • Leaf
  • Composite
  • Client
  1. scalar/primitiveなクラスとvector/containerクラスを特定する(これらはインターフェースを継承する)
  2. すべての具象クラス間をやり取り可能にさせるインターフェースを作る
  3. 具象クラスをインターフェースに対して"is a"関係として宣言する
  4. すべてのcontainerクラスをインターフェースに結合する.(アップキャスト)
  5. containerクラスはポリモーフィズムを使って,子クラスへdelegateする.
#include <iostream>
#include <vector>
using namespace std;

class Component
{
public:
  virtual void traverse() = 0;
};

class Leaf: public Component
{
  int value;
public:
  Leaf(int val)
  {
    value = val;
  }
  void traverse()
  {
    cout << value << " ";
  }
};

class Composite: public Component
{
  vector<Component *> children;
public:
  void add(Component *ele)
  {
    children.push_back(ele);
  }
  void traverse()
  {
    for(int i=0;i<children.size();i++){
      children[i]->traverse();
    }
  }
};

int main()
{
  Composite containers[4];

  for(int i=0;i<4;i++){
    for(int j=0;j<3;j++){
      containers[i].add(new Leaf(i *3+j));
    }
  }

  for(int i=1;i<4;i++){
    containers[0].add(&(containers[i]));
  }

  for(int i=0;i<4;i++){
    containers[i].traverse();
    cout << endl;
  }
}