Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПИАПС / knigaVAPO_v2.doc
Скачиваний:
385
Добавлен:
17.04.2018
Размер:
35.96 Mб
Скачать

Void info() {

      cout << "Infantryman" << endl;

    }

  private:

    Infantryman() {}   

};

  

class Archer: public Warrior

{

    friend class PrototypeFactory;

  public:  

    Warrior* clone() {

      return new Archer( *this);

    

    void info() {

      cout << "Archer" << endl;

    }

  private: 

    Archer() {}

};

  

class Horseman: public Warrior

{

    friend class PrototypeFactory;

  public:   

    Warrior* clone() {

      return new Horseman( *this);

    }

    void info() {

      cout << "Horseman" << endl;

    }

  private: 

    Horseman() {}

};

  

  

// Фабрика для создания боевых единиц всех родов войск

class PrototypeFactory

{

  public:  

    Warrior* createInfantrman() {      

      static Infantryman prototype;

      return prototype.clone();

    }

    Warrior* createArcher() {      

      static Archer prototype;

      return prototype.clone();

    }

    Warrior* createHorseman() {    

      static Horseman prototype;

      return prototype.clone();

    }

};

  

  

int main()

{   

  PrototypeFactory factory;

  vector<Warrior*> v;

  v.push_back( factory.createInfantrman());

  v.push_back( factory.createArcher());

  v.push_back( factory.createHorseman());  

  

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

    v[i]->info();

    // ...

}

В приведенной реализации для упрощения кода реестр прототипов не ведется. Воины всех родов войск создаются при помощи соответствующих методов фабричного класса PrototypeFactory, где и определены прототипы в виде статических переменных.

Результаты применения паттерна Prototype

Достоинства паттерна Prototype

  • Для создания новых объектов клиенту необязательно знать их конкретные классы.

  • Возможность гибкого управления процессом создания новых объектов за счет возможности динамических добавления и удаления прототипов в реестр.

Недостатки паттерна Prototype

Каждый тип создаваемого продукта должен реализовывать операцию клонирования clone(). В случае, если требуется глубокое копирование объекта (объект содержит ссылки или указатели на другие объекты), это может быть непростой задачей.

Родственные паттерны

В некоторых отношениях прототип и абстрактная фабрика являются кон-курентами. Но их используют и совместно. Абстрактная фабрика может хранить набор прототипов, которые клонируются и возвращают изготовленные объекты.

В тех проектах, где активно применяются паттерны компоновщик и декоратор, тоже можно извлечь пользу из прототипа.

5.4.6. Обсуждение порождающих паттернов

Есть два наиболее распространенных способа параметризовать систему клас-

сами создаваемых ей объектов. Первый способ - порождение подклассов от класса, создающего объекты. Он соответствует паттерну фабричный метод. Основной недостаток метода: требуется создавать новый подкласс лишь для того, чтобы изменить класс продукта. И таких изменений может быть очень много.

Другой способ основан на композиции объектов. Вы определяете объект, которому известно о классах объектов-продуктов, и делаете его параметром системы. Это ключевой аспект таких паттернов, как абстрактная фабрика, строитель и прототип. Для всех трех характерно создание ≪фабричного объекта≫, который изготавливает продукты.

В абстрактной фабрике фабричный объект производит объекты разных классов.

Фабричный объект строителя постепенно создает сложный продукт, следуя специальному протоколу. Фабричный объект прототипа изготавливает продукт путем копирования объекта-прототипа. В последнем случае фабричный объект

и прототип - это одно и то же, поскольку именно прототип отвечает за возврат

продукта.

Выбор паттерна зависит от многих факторов. В случае применения паттерна фабричный метод проект в большей степени поддается настройке. Другие пат-

терны нуждаются в создании новых классов, а фабричный метод - только в со-

здании одной новой операции. Часто этот паттерн рассматривается как стандартный способ создания объектов, но вряд ли его стоит рекомендовать в ситуации, когда инстанцируемый класс никогда не изменяется или когда инстанцирование выполняется внутри операции, которую легко можно заместить в подклассах (например, во время инициализации).

Проекты, в которых используются паттерны абстрактная фабрика, прототип

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

Соседние файлы в папке ПИАПС