home | login | register | DMCA | contacts | help | donate |      

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я


my bookshelf | genres | recommend | rating of books | rating of authors | reviews | new | форум | collections | читалки | авторам | add
fantasy
space fantasy
fantasy is horrors
heroic
prose
  military
  child
  russian
detective
  action
  child
  ironical
  historical
  political
western
adventure
adventure (child)
child's stories
love
religion
antique
Scientific literature
biography
business
home pets
animals
art
history
computers
linguistics
mathematics
religion
home_garden
sport
technique
publicism
philosophy
chemistry
close

Loading...


«Прототип»

Паттерн Prototype обычно применяется, когда можно заранее создать объекты всех нужных типов, просто найти среди них подходящий и клонировать его, т.?е. создавать новый объект – копию эталонного. Второе применение – это операции, аналогичные копированию-вставке (Ctrl-C, Ctrl-V). Например, если пользователь «выделил» автомобиль, скопировал его и хочет создать его дубликат – проще всего использовать данный паттерн и клонировать выделенный объект.

Для клонирования объектов нужно добавить в базовый класс метод клонирования, который обычно называют clone. Продолжим пример с автомобилями – расширим интерфейс класса Car (листинг 5).

Листинг 5


class Car

{

public:

virtual Car* clone() const = 0;

virtual const char* getName() const = 0;

virtual void setEngine(Engine* engine);

virtual Engine* getEngine() const;

virtual void setWheels(Wheel* FR, Wheel* FL, Wheel* BR, Wheel* BL);

virtual void setFrontWheels(Wheel* FR, Wheel* FL);

virtual void setBackWheels(Wheel* BR, Wheel* BL);

...

};

Теперь в потомках класса Car нужно перезагрузить и реализовать этот метод, он должен создавать абсолютно идентичную новую копию объекта (см. листинг 6).

Листинг 6


class CarBMW5: public Car

{

public:

virtual Car* clone() const

{

CarBMW5* car = new CarBMW5();

car->setEngine(getEngine()->clone());

car->setFrontWheels(getWheelFR()->clone(), getWheelFL()->clone());

car->setBackWheels(getWheelBR()->clone(), getWheelBL()->clone());

...

return car;

}

...

};

Обратите внимание, что функция клонирования CarBMW5::clone() вызывает функции клонирования для всех своих составных частей. Это стандартная практика: если использовать функцию клонирования в составном объекте, то нужно добавить ее во все объекты, которые он содержит. Таким образом, автомобиль легко клонирует себя, так как просто последовательно запускает процесс копирования всех составных частей и собирает из них новый автомобиль – свою полную копию.

Применений у этого паттерна может быть несколько, как уже было сказано выше. В случае с копированием объектов (Ctrl-C, Ctrl-V) мы будем иметь массив выделенных объектов и при нажатии на Ctrl-C просто создадим их копии, используя метод clone. А нажав на Ctrl-V, мы вставляем эти объекты в нужное место. Мы также можем заранее создать все возможные объекты (типы автомобилей) и поместить их в один массив. А потом легко создавать автомобили по имени: находим объект с нужным именем в массиве и вызываем его метод clone(). Простой пример.

class CarFactory

{

std::vector mCarTemplates;

public:

CarCreator()

{

mCarTemplates.push_back(new CarBMW5());

mCarTemplates.push_back(new CarToyotaHiace());

mCarTemplates.push_back(new CarLadaKalina());

}

Car* create(const char* name)

{

for(size_t i = 0; i < mCarTemplates.size(); ++i)

if (strcmp(mCarTemplates[i]->getName(), name) == 0)

return mCarTemplates[i]->clone();

return NULL;

}

};


«Строитель» | Журнал PC Magazine/Russian Edition #01/2009 | «Одиночка»







Loading...