Пример кода.
Такие изделия, как компьютеры и стереокомпоненты, часто имеют иерархическую структуру. Например, в раме монтируются дисковые накопители и плоские электронные платы, к шине подсоединяются различные карты, а корпус содержит раму, шины и т.д. Подобные структуры моделируются с помощью паттерна компоновщик. Класс Equipment определяет интерфейс для всех видов аппаратуры в иерархии вида часть-целое:
class Equipment { public: virtual ~Equipment (); const char* Name() { return _name; } virtual Watt Power (); virtual Currency NetPrice(); virtual Currency DiscountPrice (); virtual void Add (Equipment *); virtual void Remove (Equipment*); virtual Iterator<Equipment*>* Createlterator (); protected: Equipment (const char*); private: const char* _name; };
В классе Equipment объявлены операции, которые возвращают атрибуты аппаратного блока, например энергопотребление и стоимость. Подклассы реализуют эти операции для конкретных видов оборудования. Класс Equipment объявляет также операцию Createlterator, возвращающую итератор Iterator (см. приложение С) для доступа к отдельным частям. Реализация этой операции по умолчанию возвращает итератор Null Iterator, умеющий обходить только пустое множество. Среди подклассов Equipment могут быть листовые классы, представляющие дисковые накопители, СБИС и переключатели:
class FloppyDisk: public Equipment { public: FloppyDisk(const char*); virtual ~FloppyDisk(); virtual Watt Power(); virtual Currency NetPriceO; virtual Currency DiscountPrice(); };
CompositeEquipment - это базовый класс для оборудования, содержащего другое оборудование. Одновременно это подкласс класса Equipment:
class CompositeEquipment: public Equipment { public: virtual ~CompositeEquipment(); virtual Watt Power(); virtual Currency NetPriceO; virtual Currency DiscountPrice(); virtual void Add(Equipment*); virtual void Remove(Equipment*); virtual Iterator<Equipment*>* Createlterator(); protected: CompositeEquipment(const char*); private: List<Equipment*> _equipment; };
CompositeEquipment определяет операции для доступа и управления внутренними аппаратными блоками. Операции Add и Remove добавляют и удаляют оборудование из списка, хранящегося в переменной-члене _equipment. Операция Createlterator возвращает итератор (точнее, экземпляр класса List Iterator), который будет обходить этот список.
Подразумеваемая реализация операции NetPrice могла бы использовать Createlterator для суммирования цен на отдельные блоки:
Currency CompositeEquipment::NetPrice () { Iterator<Equipment*>* i = Createlterator(); Currency total = 0; for (i->First();!i->IsDone(); i->Next()) { total += i->CurrentItem()->NetPrice(); } delete i; return total; }
Примечание: Очень легко забыть об удалении итератора после завершения работы с ним. При обсуждении паттерна итератор рассказано, как защититься от таких ошибок.
Теперь мы можем представить аппаратный блок компьютера в виде подкласса к CompositeEquipment под названием Chassis. Chassis наследует порожденные операции класса CompositeEquipment.
class Chassis: public CompositeEquipment { public: Chassis(const char*); virtual ~Chassis(); virtual Watt Power(); virtual Currency NetPriceO; virtual Currency DiscountPrice(); };
Мы можем аналогично определить и другие контейнеры для оборудования, например Cabinet (корпус) и Bus (шина). Этого вполне достаточно для сборки из отдельных блоков довольно простого персонального компьютера:
Cabinet* cabinet = new Cabinet("PC Cabinet"); Chassis* chassis = new Chassis("PC Chassis"); cabinet->Add(chassis); Bus* bus = new Bus("MCA Bus"); bus->Add(new Card("16Mbs Token R i n g ")); chassis->Add(bus); chassis->Add(new FloppyDisk("3.Sin Floppy")); cout «"Полная стоимость равна " «chassis->NetPrice() «endl;
|