Главная

Шаблоны проектирования за 5 минут

Инструменты для решения повседневных задач

Поделиться:
 

24+

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

На сегодняшний день существует 23 шаблона проектирования, которые сгруппированы в три основные категории:
1. порождающие (с англ. creational),
2. поведенческие (с англ. behavioral),
3. структурные (с англ. structural).
В этой статье я сделаю обзор на все категории, а также реализую по одному шаблону из каждой из них.

Порождающие шаблоны(creational)

Порождающие шаблоны занимаются (на удивление) созданием объектов. Основная задача этих шаблонов состоит в том, чтобы изолировать систему от какой-либо информации о создании объектов. Это восходит к принципам ОПП, в частности инкапсуляции и абстракции.
Итак, существует пять порождающих шаблонов.
1. Строитель (builder)
2. Фабричный метод (factory method)
3. Абстрактная Фабрика (abstract Factory)
4. Одиночка (singleton)
5. Прототип (prototype)

Строитель

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

Каждый покупатель обязан указать год, марку и модель своего автомобиля. Он также может предоставить данные об отделке, цвете, пробеге и идентификационном номере автомобиля (a.k.a VIN). В таком случае у вас может возникнуть соблазн создать конструктор со всеми необходимыми данными, а затем создать методы перегрузки для каждой порции дополнительных данных.

Однако все может очень быстро испортиться, ибо невозможно предсказать, какие данные предоставит клиент, помимо необходимых. Может быть, клиент знает VIN и цвет, или отделку / VIN или пробег и VIN и цвет. В результате у вас будет невероятно много перегруженных методов. Разработчики часто сталкивались с подобной проблемой и поэтому решили создать шаблон, ныне именуемый строителем (с англ. builder)
Вот реализация вышеописанной задачи на языке программирования Java:

В методе isValid я возвращаю «true» для краткости, но вам нужно будет добавить проверку в соответствии с вашими требованиями. Затем вы можете использовать свой CarBuilder для создания подобных экземпляров.

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

Поведенческие Шаблоны

Поведенческие шаблоны управляют взаимодействием объектов. Это взаимодействие включает в себя общение друг с другом, зависимости друг от друга, изоляцию друг от друга. Цель применения поведенческих шаблонов — гибкий, обслуживаемый и тестируемый код.
В настоящее время существует одиннадцать моделей поведения.
• Шаблонный метод (template method)
• Цепочка обязанностей (Chain of Responsibility)
• Команда (Command)
 Стратегия (Strategy)
• Итератор (Iterator)
• Посетитель (Visitor)
• Посредник (Mediator)
• Memento
• Наблюдатель (Observer)
• Интерпретатор (Interpreter)
• Состояние (State)

Шаблонный метод

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

Допустим, вы захотели испечь торт. Во-первых, вам нужно будет купить все ингредиенты, если у вас их нет, затем вам также нужно будет следовать рецепту и выполнять каждый шаг в определенном порядке. Если бы вы следовали рецепту в неправильном порядке, у вас бы получилось что-то похожее, но не торт. У шаблонного метода схожая концепция. У вас есть абстрактный класс с вспомогательными методами, такими как:
1. gatherIngredients
2.
 mixWetIngredients
3.
 mixDryIngredients
4.
 mixMixedWetAndMixedDryIngredients
5.
 bake
Также есть неабстрактный метод execute. С помощью execute вы будете вызывать вспомогательные методы в нужном порядке, чтобы испечь торт.
Вот реализация:

Затем, когда вы захотите создать класс CupCake, вы просто расширите класс Cake и переопределите абстрактные методы, подобно этому:

Вы можете использовать класс CupCake так:

После запуска метода execute output должен выглядеть следующим образом:

Метод execute обеспечивает выполнение всех действий в правильном порядке.

Структурные шаблоны

Структурные шаблоны — это шаблоны, которые упрощают проектирование, определяя простой способ реализации отношений между объектами.
В настоящее время существует семь структурных шаблонов:
1. Приспособленец (flyweight)
2. Компоновщик (composite)
3. Адаптер (adapter)
4. Мост (bridge)
5. Фасад (facade)
6. Декоратор (decorator)
7. Заместитель (proxy)

Приспособленец

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

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

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

Затем мы создадим интерфейс Boligrafo (boligrafo — с испанского перо).

Далее создадим класс ручки, который реализует интерфейс Boligrafo. Вы могли бы также создать простой класс, но лучше реализовать интерфейс.

Затем нужно реализовать еще и шаблон Фабрики, который будет создавать новую ручку только тогда, когда нет совпадения для уникального ключа, который вы получаете, комбинируя тип и цвет пера.
Фабрика будет выглядеть следующим образом:

Теперь вы сможете использовать PenFactory так:

Если вы проверите результат(output), хеш-код для объектов redGelPen и anotherRedGelPen одинаков, но объекты blueMarkerPen и purpleStylusPen различаются. В итоге это взаимно-однозначное сопоставление ключей и объектов. Как только вы исчерпаете комбинации типов и цветов, новые объекты создаваться не будут, поскольку они будут соответствовать каждому критерию комбинации.
Спасибо!
Вот вам еще статьи для чтения:
S.O.L.I.D Principles Explained In Five Minutes
Creational Design Pattern: Singleton

24+