- 1. Цели
- 2. Проблематика
- 3. Обсуждение
- 4. Структура
- 5. Пример
- 6. Контрольный список
- 7. Эмпирические правила
Цели
- Указать типы объектов для создания с использованием экземпляра прототипа и создать новые объекты, скопировав этот прототип.
- Coздать один экземпляр класса для использования в качестве исходника всех будущих экземпляров.
- Оператор new считается вредным
Проблематика
Приложение имеет жёсткую привязку к классу объекта при использовании оператора new.
Обсуждение
Объявите абстрактный базовый класс, который определяет чистый виртуальный метод «clone» и поддерживает словарь всех «клонируемых» конкретных производных классов. Любой класс, который нуждается в возможности «полиморфного конструктора»: извлекается из абстрактного базового класса, регистрирует его прототипический экземпляр и реализует операцию clone().
Затем клиент вместо того, чтобы писать код, который вызывает оператор new по имени производного класса, вызывает операцию «clone» в абстрактном базовом классе, предоставляя строковый или нумерованный тип данных, который обозначает конкретный желаемый производный класс.
Структура
Фабрика знает, как найти правильный прототип, и каждый Класс знает, как порождать новые экземпляры самого себя.
Пример
Шаблон Prototype указывает тип объектов, создаваемых с использованием прототипа. Прототипы новых продуктов часто строятся до полного производства, но в этом примере прототип является пассивным и не участвует в копировании. Митотическое деление клетки, приводящее к двум идентичным клеткам, является примером прототипа, который играет активную роль в копировании и, таким образом, демонстрирует образец прототипа. Когда клетка расщепляется, появляются две клетки идентичного генотипа. Другими словами, клетка сама себя клонирует.
Контрольный список
- Добавить метод "clone" к существующей иерархии классов
- Создайте «реестр», который поддерживает кеш прототипических объектов. Реестр может быть инкапсулирован в новый класс Factory или в базовый класс.
- Создайте фабричный метод, который: может (или может быть нет) принимать аргументы, находить правильный объект-прототип, вызывать clone() для этого объекта и возвращать результат.
- Клиент заменяет все вызовы оператора new вызовами заводского метода.
Эмпирические правила
- Иногда шаблонами создания являются конкуренты: бывают случаи, когда можно использовать Prototype или Abstract Factory. В других случаях они дополняют друг друга: Abstract Factory может хранить набор прототипов, из которых можно клонировать и возвращать объекты. Abstract Factory, Builder и Prototype могут использовать Singleton в своих реализациях.
- Классы Abstract Factory часто реализуются с помощью Factory Methods, но они могут быть реализованы с использованием Prototype.
- Фабричный метод: создание через наследование. Прототип: создание через делегирование.
- Часто проекты начинаются с использования Factory Method (менее сложные, настраиваемые, подклассы размножаются) и развиваются в направлении Abstract Factory, Prototype или Builder (более гибкие, более сложные), поскольку разработчик обнаруживает, что требуется больше гибкости.
- Прототип не требует подклассов, но для этого требуется операция «initialize». Фабричный метод требует подклассификации, но не требует инициализации.
- Конструкции, которые часто используют шаблоны Composite и Decorator, часто могут также использовать Prototype.
- Прототип создаёт один экземпляр класса для использования в качестве создателя всех будущих экземпляров.
- Прототипы полезны, когда инициализация объектов стоит дорого, и вы ожидаете незначительных изменений параметров инициализации. В этом контексте Prototype может избежать дорогостоящего «создания с нуля» и поддерживать дешевое клонирование предварительно инициализированного прототипа.
- Прототип уникален среди других шаблонов создания, поскольку для него не требуется класс - только объект. Объектно-ориентированные языки, такие как Self и Omega, которые устраняют классы, полностью полагаются на прототипы для создания новых объектов.