Найти тему
using Dev

Строитель C#

Оглавление

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

Данный шаблон используется в случае, если:

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

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

Обратите внимание:

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

Шаблон Строитель включает двух участников процесса:

  • Строитель (Builder) – предоставляет методы для сборки частей объекта, при необходимости преобразовывает исходные данные в нужный вид, создает и выдает объект;
  • Распорядитель (Director) – определяет стратегию сборки: собирает данные и определяет порядок вызовов методов Строителя.

Может возникнуть вопрос: если можно напрямую вызывать методы Строителя, то зачем нужен Распорядитель? Его задача – сокрытие стратегии сборки. Это позволит, при необходимости, модифицировать или даже полностью менять ее, не затрагивая остальной код.

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

Схожие шаблоны и их отличия

-2

Реализация шаблона в общем виде

  • определяем шаги конструирования сложного объекта, и на их основе разрабатываем интерфейс Строителя IBuilder;
  • если планируется несколько стратегий сборки, то создаем интерфейс Распорядителя IDirector;
  • разрабатываем класс Распорядителя MyDirector (реализующий IDirector), работающий со Строителями через интерфейс IBuilder;
  • создаем класс Строителя MyBuilder, реализующий интерфейс IBuilder и метод получения результата;
  • в клиентском коде экземпляру MyDirector передаем интерфейс IBuilder экземпляра MyBuilder;
  • запускаем процесс сборки, вызвав метод Распорядителя;
  • получаем созданный экземпляр MyProduct у используемой реализации Строителя MyBuilder.

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

Пример реализации

Создадим класс телефона Phone который будет являться результатом производства нашей системы

-3

Создадим интерфейс разработчика телефонов IDeveloper

-4

Создадим конкретный класс разработчика телефонов, реализующий интерфейс IDeveloper

-5

По аналогии создадим класс IphoneDeveloper

-6

Для управления разработчиками создаем класс Director

-7

Посмотрим применение

-8

Запустим программу

-9

Наука
7 млн интересуются