Идея паттерна Прототип (Prototype)

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

Как я уже писал ранее, существует три вида паттернов проектирования:

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

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

Архитектура шаблона Prototype

Прототип (Prototype)

Прототип (Prototype)

  • Client — использует экземпляры классов и создает новые при помощи клонирования
  • Prototype — базовый абстрактный класс или интерфейс определяющий прототип и метод клонирования
  • ConcretePrototype — конкретные наследники базового класса или интерфейса прототипирования, реализующие его. Один из экземпляров создан на основе второго.

Логика работы Прототипа

Рассмотрим основную логику работы паттерна. Здесь нам нужно немного отойти в сторону. Нужно понимать, что в языке C# существуют переменные двух типов:

  • Переменные значения — это все переменные стандартных типов данных (int, bool, double и т.д.), которые имеют фиксированный размер и хранятся в стеке.
  • Ссылочные значения — это переменные, данные которых хранятся в куче, а в стеке хранится только указатель на область памяти. В эту категорию попадают string и все другие системные или создаваемые тобой классы.

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

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

Реализация паттерна проектирования Прототип (Prototype) на языке C#

Для начала создадим обычный класс для сравнения. Он будет хранить в себе обычные текстовые данные.

Теперь создадим класс реализующий интерфейс ICloneable. Он будет практически идентичен первому, за исключением необходимости реализации метода Clone()

Обратите внимание, что выполнять клонирование объекта возможно двумя способами:

  • Поверхностное копирование — реализуется с помощью стандартного метода MemberwiseClone(). Его недостаток заключается в том, клонирование будет выполнено только для переменных хранимых по значению. Если класс содержит поля или свойства ссылочного типа, они не будут клонированы.
  • Глубокое копирование — реализуется вручную. Необходимо самому реализовать создание нового объекта со всеми полями и свойствами класса.

Теперь посмотрим как будут вести себя объекты Text и TextCloneable при копировании.

Удостовериться в правильности можно взглянув на консоль после выполнения программы

Как мы можем увидеть, в первом случае объект изначальный объект был изменен, а во втором — нет.

Исходный код приложения доступен в репозитории github.

Также рекомендую изучить статью Паттерн Фабричный метод (Factory Method)

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

[DISPLAY_ULTIMATE_PLUS]

%d такие блоггеры, как: