Читайте также:
|
|
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), который будет обходить этот список.
Подразумеваемая реализация операции Net Price могла бы использовать Createlterator для суммирования цен на отдельные блоки:1
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 Ring"));
chassis->Add(bus);
chassis->Add(new FloppyDisk("3.Sin Floppy"));
cout «"Полная стоимость равна " «chassis->NetPrice() «endl;
Известные применения
Примеры паттерна компоновщик можно найти почти во всех объектно-ориентированных системах. Первоначально класс View в схеме модель/вид/контроллер в языке Smalltalk [KP88] был компоновщиком, и почти все библиотеки для построения пользовательских интерфейсов и каркасы проектировались аналогично. Среди них ЕТ++ (со своей библиотекой VObjects [WGM88]) и Interviews (классы Styles [LCI+92], Graphics [VL88] и Glyphs [CL90]). Интересно отметить, что первоначально вид View имел несколько подвидов, то есть он был одновременно и классом Component, и классом Composite. В версии 4.0 языка Smalltalk-80 схема модель/вид/контроллер была пересмотрена, в нее ввели класс Visual-Component, подклассами которого являлись View и CompositeView.
В каркасе для построения компиляторов RTL, который написан на Smalltalk [JML92], паттерн компоновщик используется очень широко. RTLExpression -это разновидность класса Component для построения деревьев синтаксического разбора. У него есть подклассы, например Binary Express ion, потомками которого являются объекты класса RTLExpression. В совокупности эти классы определяют составную структуру для деревьев разбора. RegisterTransf'er - класс
Паттерн Decorator
Component для промежуточной формы представления программы SSA (Single Static Assignment). Листовые подклассл RegisterTransf er определяют различные статические присваивания, например:
а примитивные присваивания, которые выполняют операцию над двумя регистрами и сохраняют результат в третьем;
а присваивание, у которого есть исходный, но нет целевого регистра. Следовательно, регистр используется после возврата из процедуры;
а присваивание, у которого есть целевой, но нет исходного регистра. Это означает, что присваивание регистру происходит перед началом процедуры.
Подкласс RegisterTransf erSet является примером класса Composite для
представления присваиваний, изменяющих сразу несколько регистров.
Другой пример применения паттерна компоновщик - финансовые программы, когда инвестиционный портфель состоит их нескольких отдельных активов. Можно поддержать сложные агрегаты активов, £сли реализовать портфель в виде компоновщика, согласованного с интерфейсом каждого актива [ВЕ93].
Паттерн команда описывает, как можно компоновать и упорядочивать объекты Command с помощью класса компоновщика MacroCommand.
Родственные паттерны
Отношение компонент-родитель используется в паттерне цепочка обязанностей.
Паттерн декоратор часто применяется совместно с компоновщиком. Когда декораторы и компоновщики используются вместе, у них обычно бывает общий родительский класс. Поэтому декораторам придется поддержать интерфейс компонентов такими операциями, как Add, Remove и GetChild.
Паттерн приспособленец позволяет разделять компоненты, но ссылаться на своих родителей они уже не могут.
Итератор можно использовать для обхода составных объектов.
Посетитель локализует операции и поведение, которые в противном случае пришлось бы распределять между классами Composite и Leaf.
Дата добавления: 2015-09-11; просмотров: 92 | Поможем написать вашу работу | Нарушение авторских прав |