printСтруктурирующие паттерны

printКомпоновщик

Composite

Назначение
Компонует объекты в древовидные структуры для представления иерархии часть-целое. Позволяет клиентам единообразно трактовать индивидуальные и составные объекты.

Результаты
1. Паттерн компоновщик позволяет создавать иерархии классов, состоящие из примитивных и составных объектов. Из примитивных объектов составляются более сложные, которые, в свою очередь, участвуют в более сложных композициях и так далее.
2. Клиенты могут единообразно работать с индивидуальными и объектами и с составными структурами. Обычно клиенту неизвестно, взаимодействует ли он с простым или составным объектом. Использование паттерна упрощает код клиента, поскольку нет необходимости писать функции, ветвящиеся в зависимости от того, с объектом какого класса они работают;
3. Паттерн компоновщик облегчает добавление новых видов компонентов. Существующие классы и клиенты будут автоматически работать с новыми подклассами.
4. Иногда желательно, чтобы составной объект мог включать только определенные виды компонентов. Проверку этих ограничений нужно проводить во время выполнения, так как паттерн не позволяет проверять ограничения при компиляции.

Структура
14680.png

Реализация
// Компонент определяет интерфейс для всех объектов в иерархии,
// объявляет интерфейс для доступа к потомкам и 
// определяет реализацию операций по умолчанию, общую для всех классов
class Component {
public:
  virtual void Operation()=0;
  virtual void Add(Component *) { throw Error(); }
  virtual void Remove(Component *) {}
  virtual int ChildCount() { return 0; }
  virtual Component *GetChild(int i) { throw Error(); }
};
// Простой компонент
class Leaf : public Component {
public:
  void Operation();
};
// Составной компонент
class Composite : public Component {
  vector<Component *> comp;
public:
  void Operation()
  { for(auto c: comp)
      c->Operation();
    ...
  }
  void Add(Component *c) { comp.push_back(c); }
  void Remove(Component *c) { comp.erase(find(comp.begin(),comp.end(),c));  }
  int ChildCount() { return comp.size(); }
  Component *GetChild(int i) { return comp.at(i); }
};
loading