Шаблоны программирования на Swift: Prototype

Хотел бы представить на суд читателей новый раздел сайта — Паттерны проектирования в iOS программировании.

Wikipedia нам говорит:

Шаблон проектирования или паттерн (англ. design pattern) в разработке программного обеспечения — повторимая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста.

Для того чтобы разобраться в шаблонах программирования или шаблонах проектирования (Design pattern) я взял книгу Дмитрия Малеева
«Хрестоматия iOS паттернов. На всякий…» и читая ее, переписывал код на Swift, пытался вникнуть во все тонкости и решить все проблемы, которые мне встречались.
Материал данного раздела не претендует на уникальность, да и что может быть уникального в распространенных шаблонах объектно ориентированного программирования. Этот материал я выкладываю сюда для собственного понимания, закрепления и для обсуждения читателями. Я — не истина в последней инстанции и всегда готов выслушать критику и исправить ошибки.

Prototypeprototype

Прототип – один из самых простых паттернов, который позволяет нам получить точную копию необходимого объекта. Тоесть использовать как прототип для нового объекта.

Когда использовать:
1. У нас есть семейство схожих объектов, разница между которыми только в состоянии их полей.
2. Чтобы создать объект вам надо пройти через огонь, воду и медные трубы. Особенно если этот объект состоит из еще одной кучи объектов, многие из которых для заполнения требуют подгрузку даных из базы, веб сервисов и тому подобных источников. Часто, легче скопировать объект и поменять несколько полей
3. Нам не важно как создается объект.
4. Нам страшно лень писать иерархию фабрик (читай дальше), которые будут инкапсулировать всю противную работу создания объекта

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

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

Перейдем к примеру

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

Вывод лога в консоль:

Думаю, понятно, что при создании второго указателя secondPerson, он сослался на тот же экземпляр что и firstPerson, и поэтому изменения свойств через один указатель повлияют и на другой.

Именно для создания копии объектов в памяти следует использовать глубокое копирование, которое в Swift реализовано протоколом NSCopying, и методом этого протокола

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

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

Вполне ожидаемый лог в консоле:

И последнее, что нужно сказать про NSCopyng. Ведь мы нигде не использовали метод этого протокола. Это потому, что NSZone больше не используется в Swift  да и в Objective-C в течение длительного времени. И передающийся в этот метод аргумент игнорируется. Этот метод существует по историческим причинам.

Ну и напоследок приведу пример использования шаблона программирования Prototype, реализованного без использования протокола NSCopyng, а лишь преимущества языка программирования Swift. Как было сказано выше — шаблон прототип используется для создания экземпляра нового объекта путем копирования всех свойств существующего объекта,  создание независимого клона. Эта практика особенно полезна , когда создание нового объекта является неэффективным.


В следующей стате мы рассмотрим шаблоны программирования Factory:Шаблоны программирования на Swift: Factory

Метки:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*