Skip to content

Latest commit

 

History

History
99 lines (65 loc) · 9.62 KB

File metadata and controls

99 lines (65 loc) · 9.62 KB

Прототип

UML

Позволяет создавать новые объекты на основе некоторого объекта-прототипа.

Применимость

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

    • Такое часто бывает, если ваш код работает с объектами, поданными извне через какой-то общий интерфейс. Вы не можете привязаться к их классам, даже если бы хотели, так как их конкретные классы неизвестны.

      Паттерн Прототип предоставляет клиенту общий интерфейс для работы со всеми прототипами. Клиенту не нужно зависеть от всех классов копируемых объектов, а только от интерфейса клонирования.

  • Когда вы имеете уйму подклассов, которые отличаются начальными значениями полей. Кто-то создал эти классы, чтобы быстро создавать объекты с определённой конфигурацией.

    • Прототип предлагает использовать набор прототипов, вместо создания подклассов для популярных конфигураций объектов.

    Таким образом, вместо порождения объектов из подклассов, вы будете копировать существующие объекты-прототипы, в которых уже настроено внутреннее состояние. Это позволит избежать взрывного роста количества классов в программе и уменьшить её сложность.

Шаги реализации

!!!

(Поверхностное копирование)

(Глубокое копирование)

!!!

  1. Создайте интерфейс прототипов с единственным методом clone (Cloneable). Если у вас уже есть иерархия продуктов, метод клонирования можно объявить непосредственно в каждом из её классов.

  2. Добавьте в классы будущих прототипов альтернативный конструктор, принимающий в качестве аргумента объект текущего класса. Этот конструктор должен скопировать из поданного объекта значения всех полей, объявленных в рамках текущего класса, а затем передать выполнение родительскому конструктору, чтобы тот позаботился об остальных полях.

    Если ваш язык программирования не поддерживает перегрузку методов, то копирование значений можно проводить и в другом методе, специально созданном для этих целей. Конструктор удобнее тем, что позволяет клонировать объект за один вызов.

  3. Метод клонирования обычно состоит всего из одной строки: вызова оператора new с конструктором прототипа. Все классы, поддерживающие клонирование, должны явно определить метод clone, чтобы подать собственный класс в оператор new. В обратном случае, результатом клонирования окажется объект родительского класса.

  4. Опционально, создайте центральное хранилище прототипов. В нём можно хранить вариации объектов, возможно даже одного класса, но по-разному настроенных.

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

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

Преимущества и недостатки

+ -
Позволяет клонировать объекты, не привязываясь к их конкретным классам. Сложно клонировать составные объекты, имеющие ссылки на другие объекты.
Меньше повторяющегося кода инициализации объектов.
Ускоряет создание объектов.
Альтернатива созданию подклассов для конструирования сложных объектов.

Отношения с другими паттернами

  • Многие архитектуры начинаются с применения Фабричного метода (более простого и расширяемого через подклассы) и эволюционируют в сторону Абстрактной фабрики, Прототипа или Строителя (более гибких, но и более сложных).

  • Классы Абстрактной фабрики чаще всего реализуются с помощью Фабричного метода, хотя они могут быть построены и на основе Прототипа.

  • Если Команду нужно копировать перед вставкой в историю выполненных команд, вам может помочь Прототип.

  • Архитектура, построенная на Компоновщиках и Декораторах, часто может быть улучшена за счёт внедрения Прототипа. Он позволяет клонировать сложные структуры объектов, а не собирать их заново.

  • Прототип не опирается на наследование, но ему нужна сложная операция инициализации. Фабричный метод наоборот, построен на наследовании, но не требует сложной инициализации.

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

  • Абстрактной фабрика, Строитель и Прототип могут быть реализованы при помощи Одиночки.