Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шаблоны проектирования (порождающие).docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
261 Кб
Скачать
☆

Пример реализации шаблона «Строитель»

Приведём реализацию шаблона «Строитель» на примере построения армии.

Сделаем классы создания армий двух разных стран: Рим и Карфаген. Для простоты, будем считать, что у каждой страны есть одинаковые типы воинов.

Диаграмма классов выглядит следующим образом:

Рисунок 9 Диаграмма классов реализации создания армии на шаблоне «Строитель»

Исходный код (не показаны классы для типов армий):

public abstract class ArmyBuilder

{

private List<Warrior> _army;

public void CreateArmy()

{

_army = new List<Warrior>();

}

public abstract void AddInfantry();

public abstract void AddArcher();

public abstract void AddHorseman();

public abstract void AddCatapult();

public List<Warrior> Army { get { return _army; } }

}

public class RomanArmyBuilder : ArmyBuilder

{

public override void AddInfantry() { Army.Add(new RomanInfantryman()); }

public override void AddArcher() { Army.Add(new RomanArcher()); }

public override void AddHorseman() { Army.Add(new RomanHorseman()); }

public override void AddCatapult() { Army.Add(new RomanCatapult()); }

}

public class CarthaginianArmyBuilder : ArmyBuilder

{

public override void AddInfantry() { Army.Add(new CarthaginianInfantryman()); }

public override void AddArcher() { Army.Add(new CarthaginianArcher()); }

public override void AddHorseman() { Army.Add(new CarthaginianHorseman()); }

public override void AddCatapult() { Army.Add(new CarthaginianCatapult()); }

}

public class Director

{

public List<Warrior> CreateArmy(ArmyBuilder parArmyBuilder)

{

parArmyBuilder.CreateArmy();

parArmyBuilder.AddInfantry();

parArmyBuilder.AddArcher();

parArmyBuilder.AddHorseman();

parArmyBuilder.AddCatapult();

return parArmyBuilder.Army;

}

}

Если сравнить реализацию построения армии по шаблону «Строитель» с «Абстрактной фабрикой», то видно отличие в том, что в шаблоне «Строитель» скрыта реализация процесса создания армии.

Создание армий двух стран выглядит следующим образом:

Director director = new Director();

RomanArmyBuilder romanArmyBuilder = new RomanArmyBuilder();

CarthaginianArmyBuilder carthaginianArmyBuilder = new CarthaginianArmyBuilder();

List<Warrior> romanArmy = director.CreateArmy(romanArmyBuilder);

List<Warrior> carthaginianArmy = director.CreateArmy(carthaginianArmyBuilder);

Достоинства и недостатки

Достоинства:

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

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

Недостатки:

  • ConcreteBuilder и создаваемый им продукт жестко связаны между собой, поэтому при внесеннии изменений в класс продукта скорее всего придется соответствующим образом изменять и класс ConcreteBuilder.

Шаблон «Прототип»

Для создания новых объектов шаблон «Прототип» использует клонирование. Прототип - это уже существующий в системе объект, который поддерживает операцию клонирования, то есть умеет создавать копию самого себя. Таким образом, для создания объекта некоторого класса достаточно выполнить операцию clone() соответствующего прототипа.

Шаблон «Прототип» реализует подобное поведение следующим образом: все классы, объекты которых нужно создавать, должны быть подклассами одного общего абстрактного базового класса. Этот базовый класс должен объявлять интерфейс метода clone(). Также здесь могут объявляться виртуальными и другие общие методы, например, initialize() в случае, если после клонирования нужна инициализация вновь созданного объекта. Все производные классы должны реализовывать метод clone().

Данный шаблон можно использовать в следующих случаях:

  • Система должна оставаться независимой как от процесса создания новых объектов, так и от типов порождаемых объектов. Непосредственное использование выражения new в коде приложения считается нежелательным;

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

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

Диаграмма классов выглядит следующим образом:

Рисунок 10 Диаграмма классов для шаблона «Прототип»

Исходный код:

public abstract class Prototype

{

public abstract Prototype Clone();

}

public class Prototype1 : Prototype

{

private int _value;

public override Prototype Clone()

{

Prototype1 prototype = new Prototype1();

prototype._value = this._value;

return prototype;

}

}

public class Prototype2 : Prototype

{

private string _name;

public override Prototype Clone()

{

Prototype2 prototype = new Prototype2();

prototype._name = this._name;

return prototype;

}

}

public class Client

{

Prototype _prototype;

public void Operation(Prototype parPrototype)

{

_prototype = parPrototype.Clone();

}

}

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