Вернемся к нашей гаме. Пусть Вам нужно стоить здание. Здание строится из блоков: целых комнат или залов, панелей, перекрытий, перегородок, стен, оконных блоков, фундаментов и кирпичей. Что интересно, соединив два здания, Вы получаете осмысленый результат: другое здание. Это значит, что и само здание является блоком. В то же время, панели можно собрать из кирпича, фундаменты тоже, и так далее. Всякий блок состоит из других - а в основе пирамиды лежат голые кирпичи, деревяшки и стекла. И кстати, есть действия, которые можно применить сразу ко всему собранному блоку - его можно взорвать, перекрасить или продать - целиком, и это произойдет со всеми частями.
Стало быть, должен существовать способ, которым мы могли бы управлять однообразно любыми строительными блоками. Этот способ конечно прост: определяем абстрактный класс строительного блока так, чтобы он мог содержать набор других строительных блоков и управять ими одновременно.
Вот набросок кода. Операция 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(); };
А вот структура: