Паттерн «Строитель» (Builder). Архитектура и применение

Паттерн «Строитель» преследует две цели:

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

Классический пример последнего описан в книге «Банды четырёх» [1]. Когда в программе для чтения текста в формате RTF добавляется функционал его преобразования в форматы ASCII и TeX.

Паттерн «Строитель» отделяет конструирование сложного объекта от его представления, так что в результате одного и того же процесса конструирования могут получаться разные представления [1].

В результате алгоритм, который вызывает «Строитель» никак не связан с логикой создания объекта. Она вся реализована (точнее инкапсулирована) в «Строителе». Это делает решения на основе данного паттерна более гибкими.

Паттерн состоит из четырёх классов участников:

  • Builder – строитель;
    • Абстрактный класс. Задаёт интерфейс для создания частей результирующего объекта Product.
  • ConcretteBuilder – конкретный строитель;
    • Конструирует и собирает вместе части результирующего объекта с помощью реализации интерфейса заданного в Builder;
    • Определяет создаваемое представление и контролирует его;
    • Строит внутренне представление результирующего объекта и определяет процесс его сборки;
    • Предоставляет интерфейс для доступа к результирующему объекту.
  • Director – распорядитель;
    • Конструирует объект, пользуясь интерфейсом класса Builder.
  • Product – продукт.
    • Результирующий объект, который был создан в результате конструирования.

Ниже представлена схема архитектуры паттерна «Строитель».

Pattern Builder

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

Паттерн «Строитель» позволяет:

  • Обеспечить более высокую степень контроля над процессом создания объектов;
  • Определять внутренне содержание объектов или конфигурировать их в процессе создания;
  • Разделить процесс создания объекта и его представление.
Пример

В качестве примера использования паттерна «Строитель» можно рассмотреть программу для сборки настольной лампы. Для написания кода примера используем язык программирования C#.

Лампа состоит из опоры (bearing), плафона (lampshade), лампочки (lamp), провода (cabel) и выключателя (lampSwitch).

Выключатель после сборки может быть включен или выключен.

Ниже приведён код класса настольной лампы.

 Допустим, процесс сборки лампы включает две стадии.
  • Сборка корпуса (монтаж в опору лампочки провода и выключателя);
  • Окончательная сборка (установка на корпус плафона).

Создадим абстрактный класс «Строитель»

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

 В завершение напишем класс «Распорядитель».

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

 Частные случаи

В приведённом примере рассмотрен, так называемый, «классический» способ реализации паттерна «Строитель». Помимо этого, на практике довольно часто встречаются и другие варианты.

Как правило, все они сводятся упрощению реализации посредством исключения абстрактного класса «Строитель» (его функции берёт на себя «Конкретный строитель») или «Распорядителя» (методы «Конкретного строителя» вызываются напрямую из клиента).

Как пример, можно привести создание диалога в Android SDK.

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

К сожалению, при создании диалога в Android SDK (и ряде других подобных случаев) выполняется только первое условие. Поэтому, если в приложении применяются две подобные реализации паттерна «Строитель» или более, имеет смысл рассмотреть возможность использования «Распорядителя» или полностью вернуться к «классическому» варианту.

Источники:
  1. Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. Приёмы объектно-ориентированного проектирования. Паттерны проектирования.

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

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