Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Билеты ООП / 21. пАттерн Builder

.docx
Скачиваний:
65
Добавлен:
16.03.2016
Размер:
27.62 Кб
Скачать

Цель:

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

Плюсы:

  • позволяет изменять внутреннее представление продукта;

  • изолирует код, реализующий конструирование и представление;

  • дает более тонкий контроль над процессом конструирования.

Применение:

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

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

Рассмотрим участников шаблона:

Builder — это, собственно, и есть Строитель, представляющий собой абстрактный интерфейс для создания объекта Product по частям;

ConcreteBuilder — конкретный интерфейс Строителя. Если вы решите, что ваш Строитель собирает ПК, то конкретные строители могут создавать компьютеры разных марок, например Apple, Acer или Hewlett-Packard;

Director — класс, занимающийся конструированием объекта, используя интерфейс, представленный Строителем;

Product — итоговый продукт, получающийся в результате конструирования.

Пример: будем собирать объект HappyMeal. В первом случае вы соберете бюджетный вариант HappyMeal (маленькая порция пепси-колы, гамбургер, картошка и игрушка), а во втором — BigHappyMeal (гамбургер вы замените на бигмак и увеличите порцию напитка).

Продукт:

class HappyMeal

{

// содержит информацию о // составе HappyMeal

ArrayList parts = new ArrayList();

// Добавляете информацию // о новой составной части

public void Add(string part)

{

parts.Add(part);

}

// Выводите информацию о // всем наборе

public void Show()

{

Console.WriteLine(" Happy Meal Parts ——-");

foreach (string part in parts)

Console.WriteLine (part);

}

}

Все данные о составе HappyMeal будут храниться в массиве ArrayList. С помощью метода Add добавьте данные в ArrayList. Метод Show просто «проходит» по вашему объекту, выводя строку за строкой.

Строитель:

// "Строитель — абстрактный интерфейс для создания объекта HappyMeal по частям"

abstract class HappyMealBuilder

{

public abstract void BuildBurger();

public abstract void BuildPepsi();

public abstract void BuildFries();

public abstract void BuildToy();

public abstract HappyMeal GetProduct();

}

Конкретный Строитель 1, создающий большой HappyMeal:

// Строитель для большого // HappyMeal

class BigHappyMealBuilder : HappyMealBuilder

{

private HappyMeal happy_meal = new HappyMeal();

public override void BuildBurger()

{

happy_meal.Add("BigMac");

}

public override void BuildPepsi()

{

happy_meal.Add("Pepsi 0.7");

}

public override void BuildFries()

{

happy_meal.Add("BigFries");

}

public override void BuildToy()

{

happy_meal.Add("Two toys");

}

public override HappyMeal GetProduct()

{

return happy_meal;

}

}

Вы видите, что у данного класса есть одна переменная happy_meal, имеющая тип вашего продукта. Ее-то вы и будете использовать во всех переопределенных методах. В каждом из них вы должны добавить информацию о продукте с помощью метода Add, описанного ранее. В методе GetProduct вы просто возвращаете вашу переменную.

С маленьким HappyMeal все делается аналогично:

// Строитель для маленького // HappyMeal

class SmallHappyMealBuilder : HappyMealBuilder

{

private HappyMeal happy_meal = new HappyMeal();

public override void BuildBurger()

{

happy_meal.Add("Hamburger");

}

public override void BuildPepsi()

{

happy_meal.Add("Pepsi 0.3");

}

public override void BuildFries()

{

happy_meal.Add("SmallFries");

}

public override void BuildToy()

{

happy_meal.Add("One toy");

}

public override HappyMeal GetProduct()

{

return happy_meal;

}

}

Пришло время реализовать класс Director, который будет отвечать за конструирование объектов:

// "Этот класс будет // заниматься конструированием"

class Director

{

// Конструирование объекта // по частям

public void Construct(HappyMealBuilder builder)

{

builder.BuildBurger();

builder.BuildPepsi();

builder.BuildFries();

builder.BuildToy();

}

}

Как видно из фрагмента листинга, все действие сосредоточено вокруг метода Construct. В него вы передаете объект HappyMealBuilder, после чего начинаете пошаговую сборку, поочередно вызывая каждый из Build-методов.

Наконец поработайте с созданными вами классами:

public static void Main()

{

// Создаете класс // Director и строителей // для двух наборов // HappyMeal

Director director = new Director();

HappyMealBuilder big_hmbuilder = new BigHappyMealBuilder();

HappyMealBuilder small_hmbuilder = new SmallHappyMealBuilder();

// Конструируете два // продукта

director.Construct(big_hmbuilder);

HappyMeal hm1 = big_hmbuilder.GetProduct();

hm1.Show();

director.Construct(small_hmbuilder);

HappyMeal hm2 = small_hmbuilder.GetProduct();

hm2.Show();

// Ожидаете действия // пользователя

Console.Read();

}

Работа с созданными классами очень проста. Сначала вы создаете объект класса Director, а затем два объекта Builder, которые будут переданы в метод Construct класса Director, чтобы собрать объект HappyMeal. После конструирования очередного HappyMeal вы передаете его в переменную hm1 или hm2 типа HappyMeal и вызываете метод Show, показывающий содержимое набора.