Обзор шаблона проектирования Prototype и его реализации в Dart и Flutter

Ранее в этой серии я проанализировал один из паттернов поведенческого проектирования - Memento. На этот раз я хотел бы представить относительно простой шаблон проектирования по сравнению с другими шаблонами в этой серии, принадлежащими к категории творческих шаблонов проектирования - прототипу.

Оглавление

  • Что такое шаблон проектирования прототипа?
  • Анализ
  • Реализация
  • Другие статьи из этой серии
  • Ваш вклад

Что такое шаблон проектирования прототипа?

Прототип - это творческий шаблон дизайна, цель которого в книге GoF описана следующим образом:

Укажите типы объектов для создания с использованием прототипа и создайте новые объекты, скопировав этот прототип.

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

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

Давайте перейдем к частям анализа и реализации, чтобы понять и узнать подробности об этом шаблоне и о том, как его реализовать!

Анализ

Общая структура шаблона проектирования Prototype выглядит так:

  • Prototype - объявляет интерфейс для клонирования самого себя. Обычно это единственный метод clone, но при необходимости могут быть объявлены / определены другие методы;
  • ConcretePrototype - реализует операцию по клонированию самого себя. Помимо копирования данных исходного объекта в клон, этот метод может также обрабатывать некоторые крайние случаи процесса клонирования, связанные с клонированием связанных объектов, распутыванием рекурсивных зависимостей и т. Д .;
  • SubclassPrototype - имеет ту же цель, что и ConcretePrototype, но также может расширять базовый класс, определяя дополнительные свойства, поведение и т. д .;
  • Клиент - создает новый объект, предлагая прототипу клонировать себя.

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

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

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

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

Реализация

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

Разве не было бы неплохо иметь единый способ копирования любой формы в вашем приложении, даже не учитывая никаких подробностей об этом в вашем клиентском коде? Что ж, мы только что проанализировали шаблон проектирования «Прототип», может, попробуем?

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

На диаграмме классов ниже показана реализация шаблона проектирования Prototype:

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

  • clone () - абстрактный метод клонирования (копирования) определенной формы;
  • randomiseProperties () - абстрактный метод рандомизации значений свойств фигуры;
  • render () - абстрактный метод для визуализации фигуры. Метод используется в пользовательском интерфейсе.

Circle и Rectangle - это классы конкретных фигур, которые расширяют абстрактный класс Shape и реализуют его абстрактные методы.

PrototypeExample инициализирует и содержит несколько объектов Shape. Эти объекты отображаются в пользовательском интерфейсе с помощью метода render (). Кроме того, определенные объекты формы могут быть скопированы с помощью clone (), а их свойства могут быть рандомизированы с помощью методов randomiseProperties () соответственно.

Форма

Абстрактный класс хранит цвет фигуры и определяет несколько абстрактных методов. Также этот класс содержит несколько конструкторов:

  • Shape () - базовый конструктор для создания объекта формы с заданным значением цвета;
  • Shape.clone () - именованный конструктор для создания объекта формы как копии предоставленного значения Shape.

Формы

Circle - особый класс, определяющий форму круга. Класс определяет свойство radius, расширяет класс Shape и реализует его абстрактные методы clone (), randomiseProperties () и render ().

Прямоугольник - особый класс, определяющий форму прямоугольника. Класс определяет свойства height и width, расширяет класс Shape и реализует его абстрактные методы clone (), randomiseProperties () и render ().

Пример

Прежде всего, подготавливается файл разметки, который предоставляется как описание шаблона:

PrototypeExample содержит несколько объектов Shape - Circle и Rectangle. При нажатии кнопки Рандомизировать свойства значения свойств фигуры рандомизируются (для фигуры вызывается метод randomiseProperties ()). Кроме того, если нажата кнопка Clone, для фигуры вызывается метод clone (), и копия этой конкретной фигуры помещается в ящик с теми же значениями всех свойств. .

PrototypeExample не заботится о конкретном типе объекта формы, пока он расширяет абстрактный класс Shape и реализует все его абстрактные методы. В результате метод clone () может быть вызван для любой фигуры, все его свойства копируются, даже если они различаются для разных фигур, например у круга есть только свойство radius, специфичное для этой конкретной формы, а у прямоугольника есть два разных свойства - height и width.

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

Все изменения кода для шаблона проектирования Prototype и его пример реализации можно найти здесь.

Другие статьи из этой серии

Ваш вклад

👏 Нажмите кнопку хлопка ниже, чтобы выразить свою поддержку и побудить меня писать лучше!
💬 Оставьте отзыв на эту статью, поделившись своими мыслями, комментариями или пожеланиями относительно серии.
📢 Поделитесь этой статьей со своими друзья, коллеги в социальных сетях.
➕ Подписывайтесь на меня на Medium.
⭐ Пометьте репозиторий Github.