Что такое шаблон строителя?

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

Вместо этого можно использовать уже готовое решение. Программные элементы основаны на книге «Паттерн проектирования: Elements of Reusable Object-Oriented Software», опубликованной в 1994 году четырьмя американскими разработчиками программного обеспечения, известными как Gang of Four, или сокращенно GoF. Наше руководство познакомит вас с основными аспектами паттерна проектирования «Строитель», включая практический пример.

Шаблон «Строитель» в деталях

Шаблон строителя относится к группе паттернов построения в рамках паттернов проектирования. Он улучшает как безопасность конструирования, так и читаемость программного кода. Целью паттерна конструирования builder является создание объекта без известных конструкторов, но со вспомогательным классом.

Цитата

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

— Эрих Гамма, Ричард Хелм, Ральф Джонсон, Джон Влиссидес (= «Банда четырех»).

Источник: Design Patterns: Элементы повторно используемого объектно-ориентированного программного обеспечения 1. Издание, Издатель: Addison-Wesley Professional; 1. Edition (10th November 1994)

Шаблон проектирования строителя различает четыре действующих лица:

  • Директор: Этот агент конструирует сложный объект, используя интерфейс строителя. Ему известны требования к последовательности действий строителя. С помощью директора построение объекта отделено от заказчика («клиента»).
  • Конструктор: Предоставляет интерфейс для создания компонентов сложного объекта (или продукта).
  • Конкретный строитель: Этот агент создает части сложного объекта и определяет (и управляет) представлением объекта, а также поддерживает интерфейс для вывода объекта.
  • Продукт: Результат «деятельности» модели строителя, т.е. сложный объект, который должен быть построен.

Директор контролирует решающий процесс модели строителя: отделение создания объекта/продукта от клиента.

UML-представление модели строителя

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

Плюсы и минусы шаблона проектирования

Вот взгляд на плюсы и минусы.

Плюсы паттерна конструктора

Построение и представление (вывод) включаются отдельно. Внутренние представления конструктора скрыты от директора. Таким образом, новые представления могут быть легко интегрированы с помощью конкретных классов построителя. Процесс построения контролируется директором в явном виде. Если необходимо внести изменения, это можно сделать без согласования с клиентом.

Минусы паттерна builder

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

Когда используется паттерн конструктора?

Один из способов проиллюстрировать паттерн построения — рассмотреть пример ресторана и клиента, делающего заказ. После получения заказа сотрудники ресторана приступают к его выполнению. Весь процесс вплоть до доставки заказа происходит «за кулисами». Гость не видит, что происходит, например, на кухне, в конечном итоге ему выдается результат (на языке программирования: print).

Следующие примеры кода еще больше подчеркивают отдельные действующие лица паттерна builder.

Объект, т.е. меню, изначально пуст. Содержимое добавляется после того, как сделан заказ:

public class Menu {
	private String starter = "No starter";
	private String maincourse = "No main course";
	private String dessert = "No dessert";
	private String drink = "No drink";
	public void setstarter (String starter) {
		this.starter = starter;
	}
	public void setmaincourse (String maincourse) {
		this.maincourse = maincourse;
	}
	public void setdessert(String dessert) {
		this.dessert = dessert;
	}
	public void setdrink(String drink) {
		this.drink = drink;
	}
	public void print() {
		System.out.println(
			"The food is ready! " + "n" +
			" – Starter: " + starter +
			" – Main course: " + maincourse +
			" – Dessert: " + dessert +
			" – Drink: " + drink);
	}
}

Директор предоставляет «среду» для того, чтобы блюдо могло быть приготовлено — или построено — для гостя. Эта среда доступна каждому гостю. Гость общается только с директором, поэтому фактическое приготовление остается скрытым:

public class MattsRestaurant {
	private MenuBuilder menuBuilder;
	public void setBuilder(MenuBuilder menuBuilder) {
		this.menuBuilder = menuBuilder;
	}
	public Menu buildMenu(){
		menuBuilder.buildStarter();
		menuBuilder.buildMainCourse();
		menuBuilder.buildDessert();
		menuBuilder.buildDrink();
		return menuBuilder.build();
	}
}

Затем в действие вступает строитель. В нашем примере это шеф-повар:

public abstract class MenuBuilder {
	Menu menu = new Menu();
	abstract void buildStarter();
	abstract void buildMainCourse();
	abstract void buildDessert();
	abstract void buildDrink();
	Menu build()
{
		return menu;
	}
}

Конкретный строитель, в данном случае повар, создает (т.е. готовит) отдельные компоненты заказанного блюда. Для этого они переопределяют «абстрактные» пункты меню:

public class MenuOfTheDayBuilder extends MenuBuilder {
	@Override
	public void buildStarter() {
		burger.setStarter("Pumpkin soup");
	}
	@Override
	public void buildMainCourse() {
		burger.setMainCourse("Grilled steak with potatoes");
	}
	@Override
	public void buildDessert() {
		burger.setDessert("Vanilla ice cream");
	}
	@Override
	public void buildDrink() {
		burger.setDrink("Red wine");
	}
}

Наконец, отдельные компоненты блюда суммируются и доставляются гостю, т.е. «распечатываются».

public class Main {
	public static void main(String[] args) {
		MattsRestaurant mattsRestaurant = new MattsRestaurant();
		menuRestaurant.setBuilder(new MenuOfTheDayBuilderBuilder());
		buildMenu(menuRestaurant);
		menuRestaurant.setBuilder(new SpecialMenuBuilder());
		buildMenu(menuRestaurant);
	}
	private static void buildMenu(MattsRestaurant mattsRestaurant) {
		MenuOfTheDay menu = mattsRestaurant.buildMenu();
		menu.print();
	}
}
Примечание

Этот пример основан на коде, написанном Даниэлем Хёйером Якобсеном, который доступен на его сайте Design Patterns in Java.

Оцените статью
cdelat.ru
Добавить комментарий