Вернемся к нашей гаме. Пусть Вам нужно стоить здание. Здание строится из блоков: целых комнат или залов, панелей, перекрытий, перегородок, стен, оконных блоков, фундаментов и кирпичей. Что интересно, соединив два здания, Вы получаете осмысленый результат: другое здание. Это значит, что и само здание является блоком. В то же время, панели можно собрать из кирпича, фундаменты тоже, и так далее. Всякий блок состоит из других - а в основе пирамиды лежат голые кирпичи, деревяшки и стекла. И кстати, есть действия, которые можно применить сразу ко всему собранному блоку - его можно взорвать, перекрасить или продать - целиком, и это произойдет со всеми частями.
Стало быть, должен существовать способ, которым мы могли бы управлять однообразно любыми строительными блоками. Этот способ конечно прост: определяем абстрактный класс строительного блока так, чтобы он мог содержать набор других строительных блоков и управять ими одновременно.
Вот набросок кода. Операция doIt крупного объекта вызывает doIt для каждой из своих частей. Компоновщик удобно создавать при помощи строителя.
class CPart
{
void add (CPart* )=0;
void remove (CPart* )=0;
// Псеводокод
virtual void doIt ( ) = 0;
};
class CCompositePart
{
void add (CPart* _part) {m_list.add(_part); };
void remove (CPart* _part) {m_list.remove(_part); };
// Псеводокод
virtual void doIt ( )
{
// выполнить doIt() для всех объектов в коллекции m_list
};
private:
CList<CPart*> m_list;
};
class CBuilding : public CCompositePart
{
// ...
void doIt();
};
class CBrick : public CPart
{
// ...
void doIt();
};
А вот структура:
