русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


Реалізація патерна Factory Method


Дата додавання: 2014-10-07; переглядів: 960.


 

Розглянемо обидва варіанти реалізації паттерна Factory Method на прикладі процесу породження військових персонажів для нашої стратегічної гри. Її докладний опис можна знайти в розділі Що породжують патерни. Для спрощення демонстраційного коду будемо створювати військові персонажі для якоїсь абстрактної армії без урахування особливостей воюючих сторін.

 

// #include <iostream>

#include <vector>

 

enum Warrior_ID { Infantryman_ID=0, Archer_ID, Horseman_ID };

 

// Иерархия классов игровых персонажей

class Warrior

{

public:

virtual void info() = 0;

virtual ~Warrior() {}

// Параметризированный статический фабричный метод

static Warrior* createWarrior( Warrior_ID id );

};

 

class Infantryman: public Warrior

{

public:

void info() {

cout << "Infantryman" << endl;

}

};

 

class Archer: public Warrior

{

public:

void info() {

cout << "Archer" << endl;

}

};

 

class Horseman: public Warrior

{

public:

void info() {

cout << "Horseman" << endl;

}

};

 

 

// Реализация параметризированного фабричного метода

Warrior* Warrior::createWarrior( Warrior_ID id )

{

Warrior * p;

switch (id)

{

case Infantryman_ID:

p = new Infantryman();

break;

case Archer_ID:

p = new Archer();

break;

case Horseman_ID:

p = new Horseman();

break;

default:

assert( false);

}

return p;

};

 

 

// Создание объектов при помощи параметризированного фабричного метода

int main()

{

vector<Warrior*> v;

v.push_back( Warrior::createWarrior( Infantryman_ID));

v.push_back( Warrior::createWarrior( Archer_ID));

v.push_back( Warrior::createWarrior( Horseman_ID));

 

for(int i=0; i<v.size(); i++)

v[i]->info();

// ...

}

 

Представлений варіант паттерна Factory Method користується популярністю завдяки своїй простоті. У ньому статичний фабричний метод createWarrior () визначений безпосередньо в полиморфном базовому класі Warrior. Цей фабричний метод є параметризованих, тобто для створення об'єкта деякого типу в createWarrior () передається відповідний ідентифікатор типу.

З точки зору "чистоти" об'єктно-орієнтованого коду у цього варіанту є такі недоліки:

· Так як код по створенню об'єктів усіх можливих типів зосереджений в статичному фабричному методі класу Warrior, то базовий клас Warrior володіє знанням про всі похідних від нього класах, що є нетиповим для об'єктно-орієнтованого підходу.

· Подібне використання оператора switch (як в коді фабричного методу createWarrior ()) в об'єктно-орієнтованому програмуванні також не вітається.

Зазначені недоліки відсутні в класичній реалізації патерна Factory Method.

 

//

#include <iostream>

#include <vector>

 

// Иерархия классов игровых персонажей

class Warrior

{

public:

virtual void info() = 0;

virtual ~Warrior() {}

};

 

class Infantryman: public Warrior

{

public:

void info() {

cout << "Infantryman" << endl;

};

};

 

class Archer: public Warrior

{

public:

void info() {

cout << "Archer" << endl;

};

};

 

class Horseman: public Warrior

{

public:

void info() {

cout << "Horseman" << endl;

};

};

 

 

// Фабрики объектов

class Factory

{

public:

virtual Warrior* createWarrior() = 0;

virtual ~Factory() {}

};

 

class InfantryFactory: public Factory

{

public:

Warrior* createWarrior() {

return new Infantryman;

}

};

 

class ArchersFactory: public Factory

{

public:

Warrior* createWarrior() {

return new Archer;

}

};

 

class CavalryFactory: public Factory

{

public:

Warrior* createWarrior() {

return new Horseman;

}

};

 

 

// Создание объектов при помощи фабрик объектов

int main()

{

InfantryFactory* infantry_factory = new InfantryFactory;

ArchersFactory* archers_factory = new ArchersFactory ;

CavalryFactory* cavalry_factory = new CavalryFactory ;

 

vector<Warrior*> v;

v.push_back( infantry_factory->createWarrior());

v.push_back( archers_factory->createWarrior());

v.push_back( cavalry_factory->createWarrior());

 

for(int i=0; i<v.size(); i++)

v[i]->info();

// ...

}

 

Класичний варіант паттерна Factory Method використовує ідею полиморфной фабрики. Спеціально виділений для створення об'єктів поліморфний базовий клас Factory оголошує інтерфейс фабричного методу createWarrior (), а похідні класи його реалізують.

Представлений варіант паттерна Factory Method є найбільш поширеним, але не єдиним.

 

Можливі такі варіації:

 

· Клас Factory має реалізацію фабричного методу createWarrior () за замовчуванням.

· Фабричний метод createWarrior () класу Factory параметризованих типом створюваного об'єкта (як і у представленого раніше, простого варіанту Factory Method) і має реалізацію за замовчуванням. В цьому випадку, похідні від Factory класи необхідні лише для того, щоб визначити нестандартну поведінку createWarrior ().


<== попередня лекція | наступна лекція ==>
UML-діаграма класів патерна Factory Method. Класична реалізація | Результати застосування патерну Factory Method


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн