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...


«Абстрактная фабрика»

Шаблон Abstract Factory предоставляет интерфейс для создания семейств связанных или зависимых объектов, позволяя не указывать их конкретные классы. Обычно он применяется, когда нужно создавать составные объекты из конкретных частей (объектов). Классический пример – автомобиль. Если есть классы для разных частей автомобиля, то конкретный автомобиль будет состоять из множества таких частей, причем в каждой марке автомобиля будут конкретные части-детали. Для окончательной сборки автомобиля можно использовать «Абстрактную фабрику», классы-потомки которой будут создавать конкретные автомобили.

class AbstractCarFactory

{

public:

virtual Car* createCar() = 0;

virtual Engine* createEngine() = 0;

virtual Wheel* createWheel() = 0;

...

};

Нам также понадобятся иерархии классов для каждой из частей автомобиля (см. листинг 2).

Листинг 2


class Engine

{

public:

virtual void setSpeedLimit(int kmph);

virtual void addOil(float amount);

...

};

class Wheel

{

float mRadius;

public:

Wheel(float radius): mRadius(radius) {};

virtual float getRadius() const {return mRadius;}

...

};

class Car

{

public:

virtual const char* getName() const = 0;

virtual void setEngine(Engine* engine);

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);

...

};

Процедура сборки итогового объекта приводится в листинге 3.

Листинг 3


Car* createCar(AbstractCarFactory* carFactory)

{

Car* car = carFactory->createCar();

Engine* engine = carFactory->createEngine();

car->setEngine(engine);

car->setWheels(carFactory->createWheel(), carFactory->createWheel(), сarFactory->createWheel(), carFactory->createWheel());

// дальше может идти сколько угодно сложный код для «сборки» готового автомобиля из частей

return car;

}

Для добавления конкретных моделей автомобилей нужно просто создать новый класс, породив его от AbstractCarFactory. Задача этого класса – создать конкретные детали автомобиля. Понадобится также создать классы этих конкретных деталей, если их еще нет.

class BMW5CarFactory: public AbstractCarFactory

{

рublic:

virtual Car* createCar() {return new CarBMW5();}

virtual Engine* createEngine() {return new EngineBMW5();}

virtual Wheel* createWheel() {return new WheelNokian(16);}

...

};

class CarBMW5: public Car

{

public:

virtual const char* getName() const {return «BMW5»;}

...

};

Главный недостаток этого паттерна состоит в том, что со временем становится труднее вносить изменения в структуру классов. Например, если у нас уже имеется 100 конкретных моделей автомобилей, а мы решили добавить в AbstractCarFactory новую функцию, создающую фары, то нам придется изменить все 100 классов-потомков, создающих конкретные модели.


«Фабричный метод» | Журнал PC Magazine/Russian Edition #01/2009 | «Строитель»







Loading...