Design Patterns — A quick guide to Facade pattern.

Паттерны проектирования — краткое руководство по применению паттерна Фасад

Nikita Goncharuk
Clean Code

--

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

Паттерн Фасад относится к структурным паттернам проектирования. Структурные паттерны проектирования всецело связаны с Классами и Объектами и при создании интерфейсов используют наследование. Структурные объекты-паттерны определяют способы создания объектов, расширяющих функциональные возможности [доступным и понятным языком о паттернах написано в Design Patterns].

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

Шаг 1 — Ключевые Слова

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

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

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

Шаг 2 — Схема

Эта схема основана на вышеприведенном примере. Для удобства восприятия разделим её на три части.

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

Шаг 3 — Пример кода

Предлагаю скопировать код из моего git-репозитория “Andreas Poyias” или из приведенных ниже фрагментов (класс за классом, в указанной последовательности), вставить его в любой из доступных онлайн-редакторов C++ (например, c++ shell, jdoodle, onlineGDB) и запустить, чтобы увидеть результат. После прочитайте комментарии или описание (ниже). Не торопитесь, читайте внимательно (приблизительно минуту, не меньше и не больше).

Подсистемы

Подсистемами в нашем примере являются Waiter_Subsystem1 и Kitchen_Subsystem2. На первый взгляд, каждая подсистема кажется независимой, так как может самостоятельно выполнять некоторые задачи. Но так ли это?

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

Основная функция

Основная функция работает в качестве клиента (так же, как и в предыдущих руководствах). Клиент может просто создать экземпляр Фасада и вызвать функцию, которая выполнит всю работу.

Использование паттерна Фасад будет более эффективным, если разобраться в его преимуществах и понять в каких случаях его применение целесообразно.

  • Фасад создает более высокоуровневый интерфейс, который с помощью обертки упрощает использование сложной подсистемы.
  • Это уменьшает затраты времени для обучения использования подсистемы.
  • Фасад cпособствует отделению подсистемы от ее потенциальных клиентов.
  • Если Фасад является единственной точкой входа в подсистему — он ограничивает “опытных пользователей” в плане гибкого использования всех «фишек» системы.

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

Translated: medium

--

--