Образец прототипа - Prototype pattern

В образец прототипа творческий шаблон дизайна в разработка программного обеспечения. Используется, когда тип объекты создать определяется прототип пример, который клонируется для создания новых объектов. Этот шаблон используется для:

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

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

Клиент, вместо того чтобы писать код, который вызывает оператор «новый» для жестко заданного имени класса, вызывает клон () в прототипе, вызывает заводской метод с параметр обозначение конкретного бетона производный класс желаемый, или вызывает клон () через некоторый механизм, предоставляемый другим шаблоном проектирования.

В митотическое деление ячейки, в результате чего образуются две идентичные ячейки, является примером прототипа, который играет активную роль в копировании самого себя и, таким образом, демонстрирует шаблон прототипа. Когда клетка расщепляется, возникают две клетки с одинаковым генотипом. Другими словами, клетка клонирует себя.[1]

Обзор

Прототип[2]шаблон дизайна - один из двадцати трех хорошо известных Шаблоны проектирования GoF в которых описывается, как решать повторяющиеся проблемы проектирования для разработки гибкого и многократно используемого объектно-ориентированного программного обеспечения, то есть объектов, которые легче реализовать, изменить, протестировать и повторно использовать.

Шаблон проектирования прототипа решает такие проблемы, как:[3]

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

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

Шаблон проектирования прототипа описывает, как решать такие проблемы:

  • Определить Прототип объект, который возвращает свою копию.
  • Создавайте новые объекты, копируя Прототип объект.

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

Структура

Схема классов и последовательности UML

Пример класса UML и диаграмма последовательности для шаблона проектирования Prototype.

В приведенном выше UML диаграмма классов, то Клиент класс, который требует Товар объект не создает экземпляр Товар1 class напрямую. Клиент относится к Прототип интерфейс для клонирования объекта. Товар1 класс реализует Прототип интерфейс, создав свою копию.
В UML схема последовательности показывает взаимодействия во время выполнения: Клиент вызовы объектов клон () на прототип: Product1 объект, который создает и возвращает свою копию (a product: Продукт1 объект).

Диаграмма классов UML

UML диаграмма классов, описывающая шаблон проектирования прототипа

Эмпирические правила

Иногда творческие шаблоны перекрытие - бывают случаи, когда либо прототип, либо абстрактная фабрика было бы уместно. В других случаях они дополняют друг друга: абстрактная фабрика может хранить набор прототипов, из которых можно клонировать и возвращать объекты продукта (GoF, стр. 126). Абстрактная фабрика, строитель, а прототип может использовать одиночка в их реализациях. (GoF, стр. 81, 134). Абстрактные фабричные классы часто реализуются фабричными методами (создание через наследство ), но их можно реализовать с помощью прототипа (создание через делегация ). (GoF, стр.95)

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

Прототип не требует создания подклассов, но требует операции «инициализации». Фабричный метод требует создания подклассов, но не требует инициализации. (GoF, стр. 116)

Дизайны, в которых интенсивно используется составной и декоратор шаблоны часто также могут извлечь выгоду из Prototype. (GoF, стр. 126)

Практическое правило может заключаться в том, что вам нужно clone () Объект когда вы хотите создать другой объект во время выполнения это подлинная копия клонируемого объекта. Подлинная копия означает, что все атрибуты вновь созданного объекта должны быть такими же, как и у объекта, который вы клонируете. Если бы вы могли созданный класс, используя новый вместо этого вы получите объект со всеми атрибутами в качестве их начальных значений. Например, если вы разрабатываете систему для выполнения транзакций с банковским счетом, то вам нужно сделать копию объекта, который содержит информацию о вашей учетной записи, выполнять транзакции на его, а затем замените исходный Объект измененным. В таких случаях вы захотите использовать clone () вместо new.

Примеры кода

Псевдокод

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

класс Слово является    поле происшествия является        Список индекса каждого вхождения слова в текст. конструктор WordOccurrences (текст, слово) является            ввод: то текст в котором должны быть найдены вхождения ввод: то слово который должен появиться в тексте. Очистите происшествия список для каждого textIndex в text isMatching: = true для каждого wordIndex в слово если текущий символ слова не соответствует текущему текстовому символу тогда                    isMatching: = false если isMatching верно тогда                Добавить текущий textIndex в происшествия список метод getOneOccurrenceIndex (n) является            ввод: число, чтобы указать на пй вхождение. вывод: индекс пое вхождение. Вернуть пй пункт происшествия поле, если есть. метод клон () является            вывод: объект WordOccurrences, содержащий те же данные. Вызовите clone () суперкласса. На возвращенном объекте установите происшествия поле со значением локального происшествия поле. Верните клонированный объект. Text: = "Шаблон прототипа - это шаблон проектирования в разработке программного обеспечения, впервые описанный в шаблонах проектирования, книге." Word: = "pattern" dsearchEngine: = new WordOccurrences (text, word) anotherSearchEngine: = searchEngine .clone ()

(алгоритм поиска не оптимизирован; это базовый алгоритм для иллюстрации реализации шаблона)

Пример C #

Этот шаблон создает конкретный тип объекта, используя его прототип. Другими словами, при создании объекта Prototype, класс фактически создает его клон и возвращает его как прототип. Как видите, мы использовали метод MemberwiseClone для клонирования прототипа при необходимости.

общественный Абстрактные класс Прототип{    // нормальная реализация    общественный Абстрактные Прототип Клонировать();}общественный класс ConcretePrototype1 : Прототип{    общественный отменять Прототип Клонировать()    {        вернуть (Прототип)этот.MemberwiseClone(); // Клонирует конкретный класс.    }}общественный класс БетонПрототип2 : Прототип{    общественный отменять Прототип Клонировать()    {        вернуть (Прототип)этот.MemberwiseClone(); // Клонирует конкретный класс.    }}

Пример C ++

Обсуждение шаблона проектирования вместе с полным иллюстративным примером реализации с использованием дизайна полиморфного класса представлены в разделе Аннотации C ++.

Пример Java

Этот шаблон создает вид объекта, используя его прототип. Другими словами, при создании объекта Prototype, класс создает его клон и возвращает его как прототип. При необходимости для клонирования прототипа использовался метод клонирования.

// Прототип шаблонаобщественный Абстрактные класс Прототип орудия Клонируемый {    общественный Прототип клон() бросает CloneNotSupportedException{        вернуть (Прототип) супер.клон();    }}	общественный класс ConcretePrototype1 расширяет Прототип {    @Override    общественный Прототип клон() бросает CloneNotSupportedException {        вернуть (ConcretePrototype1)супер.клон();    }}общественный класс БетонПрототип2 расширяет Прототип {    @Override    общественный Прототип клон() бросает CloneNotSupportedException {        вернуть (БетонПрототип2)супер.клон();    }}

Пример PHP

// Шаблон Prototype в PHP выполняется с использованием встроенной функции PHP __clone ()Абстрактные класс Прототип{    общественный строка $ а;    общественный строка $ млрд;        общественный функция displayCONS(): пустота    {        эхо "МИНУСЫ: {$ это->а} п";        эхо "МИНУСЫ: {$ это->б} п";    }        общественный функция displayCLON(): пустота    {        эхо «КЛОН: {$ это->а} п";        эхо «КЛОН: {$ это->б} п";    }    Абстрактные функция __clone();}класс ConcretePrototype1 расширяет Прототип{    общественный функция __construct()    {        $ это->а = «А1»;        $ это->б = «B1»;                $ это->displayCONS();    }    функция __clone()    {        $ это->displayCLON();    }}класс БетонПрототип2 расширяет Прототип{    общественный функция __construct()    {        $ это->а = «А2»;        $ это->б = "БИ 2";                $ это->displayCONS();    }    функция __clone()    {        $ это->а = $ это->а ."-C";        $ это->б = $ это->б ."-C";                $ это->displayCLON();    }}$ cP1 = новый ConcretePrototype1();$ cP2 = новый БетонПрототип2();$ cP2C = клон $ cP2;// РЕЗУЛЬТАТ: # quanton81// МИНУСЫ: A1// МИНУСЫ: B1// МИНУСЫ: A2// МИНУСЫ: B2// КЛОН: A2-C// КЛОН: B2-C

Пример Python

Python версии 3.8+

от abc импорт ABC, абстрактный методот набор текста импорт AnyStrкласс А(ABC):    "" "Абстрактный класс" ""    @abstractmethod    def кто(я) -> AnyStr:        проходяткласс Бетон(А):    "" "Класс бетона" ""    def кто(я) -> AnyStr:        "" "Переопределение метода whois () абстрактного класса A" ""        вернуть ж"Конкретный: {себя}"c = Бетон()Распечатать(c.кто())

Вывод:

Бетон: <__ main __. Бетонный объект в 0x1023bafd0>

Смотрите также

использованная литература

  1. ^ Дуэлл, Майкл (июль 1997 г.). «Непрограммные примеры шаблонов проектирования». Журнал Object. 7 (5): 54. ISSN  1055-3614.
  2. ^ Эрих Гамма; Ричард Хелм; Ральф Джонсон; Джон Влиссидес (1994). Паттерны проектирования: элементы объектно-ориентированного программного обеспечения многократного использования. Эддисон Уэсли. стр.117ff. ISBN  0-201-63361-2.
  3. ^ «Шаблон проектирования прототипа - проблема, решение и применимость». w3sDesign.com. Получено 2017-08-17.

Источники