Реализация паттерна Builder на C#
Перед изучением данной темы рекомендуется ознакомиться со следующей темой:
Содержание
- 1. Структура паттерна Builder
- 2. Реализация паттерна Builder на C#. Пример
- 3. Пример использования паттерна Builder для генерирования массивов случайных чисел
- Связанные темы
Поиск на других ресурсах:
1. Структура паттерна Builder
В наиболее общем случае структура паттерна Builder изображена на рисунке 1.
Рисунок 1. Структура паттерна Builder
⇑
2. Реализация паттерна Builder на C#. Пример
2.1. Структурная схема решения задачи
В примере демонстрируется реализация паттерна Builder на языке C#, структура которого изображена на рисунке 2.
Рисунок 2. Паттерн Builder. Построение продукта из 3-х частей
Объявляются следующие классы:
- Product — класс, который является продуктом (результатом работы паттерна). Это произвольный класс. В демонстрационных целях в этом классе объявляется три целочисленных переменных, каждая из которых условно считается частью продукта;
- Builder — абстрактный класс, который служит интерфейсом между распорядителем (Director) и классом, создающим конкретный объект (ConcreteBuilder);
- ConcreteBuilder — класс, который строит конкретный объект;
- Director — класс, являющийся распорядителем. Этот класс строит (конфигурирует) объект класса ConcreteBuilder для использования его клиентом.
- Program — класс, который выступает в роли клиента. В этом классе реализуется функция main(), в которой продемонстрирована работа клиента. Клиент обращается к распорядителю (Director) для того, чтобы тот построил объект класса ConcreteBuilder. Затем построенный объект возвращается клиенту в методе GetResult().
⇑
2.2. Программа на языке C#
Текст программы на языке программирования C# следующий
using System; namespace ConsoleApp8 { // Паттерн Builder. Пример реализации на C# // 1. Класс, служащий продуктом. Содержит три части class Product { // Внутренние переменные private int part1, part2, part3; // Конструктор public Product() { part1 = 0; part2 = 0; part3 = 0; } // Методы доступа public int GetPart1() { return part1; } public int GetPart2() { return part2; } public int GetPart3() { return part3; } public void SetPart1(int part1) { this.part1 = part1; } public void SetPart2(int part2) { this.part2 = part2; } public void SetPart3(int part3) { this.part3 = part3; } } // 2. Клас, который служит интерфейсом между распорядителем и конкретным строителем abstract class Builder { // Метод, создающий продукт public abstract void CreateProduct(); // Методы, которые строят части продукта public abstract void BuildPart1(int part); public abstract void BuildPart2(int part); public abstract void BuildPart3(int part); // Метод, возвращающий продукт клиенту public abstract Product GetProduct(); } // Класс - конкретный строитель, наследует абстрактный класс Builder class ConcreteBuilder : Builder { // Внутренняя переменная - ссылка на продукт private Product currentBuilder; // Методы, которые объявляются в абстрактном классе Builder, их нужно реализовывать public override void CreateProduct() { currentBuilder = new Product(); } public override void BuildPart1(int part) { currentBuilder.SetPart1(part); } public override void BuildPart2(int part) { currentBuilder.SetPart2(part); } public override void BuildPart3(int part) { currentBuilder.SetPart3(part); } public override Product GetProduct() { return currentBuilder; } } // Класс-распорядитель, содержит методы построения объекта Product из частей class Director { // Ссылка на Builder private Builder builder; // Конструктор - инициализируется экземпляром Builder public Director(Builder _builder) { builder = _builder; } // Метод, который строит объект класса Product из частей public void Construct() { // Построить экземпляр класса Product builder.CreateProduct(); builder.BuildPart1(10); builder.BuildPart2(20); builder.BuildPart3(30); } } // Класс, содержащий функцию клиента class Program { static void Main(string[] args) { // Это клиент // 1. Объявить ссылку на продукт Product product; // 2. Создать конкретного строителя Builder B = new ConcreteBuilder(); // 3. Создать распорядителя и сконфигурировать его строителем Director D = new Director(B); // 4. Вызвать методы построения продукта - доверить это распорядителю D.Construct(); // 5. Вернуть построенный продукт клиенту product = B.GetProduct(); // 6. Проверить, как построен продукт Console.WriteLine("product.part1 = {0}", product.GetPart1()); Console.WriteLine("product.part2 = {0}", product.GetPart2()); Console.WriteLine("product.part3 = {0}", product.GetPart3()); } } }
⇑
2.3. Результат работы программы
product.part1 = 10 product.part2 = 20 product.part3 = 30
⇑
3. Пример использования паттерна Builder для генерирования массивов случайных чисел
3.1. Условие задачи
Используя средства языка C# и возможности паттерна Builder разработать программу для генерирования объектов, являющихся массивами случайных чисел. Массивы случайных чисел представлены следующими классами:
- ArrayRandomInt — массив из целых чисел. Для данного массива указывается диапазон;
- ArrayRandomChar — массив случайных символов от ‘A’ до ‘Z’.
⇑
3.2. Рисунок, отражающий структурную схему решения задачи
На рисунке 3 изображено структуру паттерна Builder, которая отражает решение данной задачи.
Рисунок 3. Паттерн Builder. Генерирование объектов — массивов случайных чисел
Как видно из рисунка, класс-распорядитель может использовать два класса-строителя BuildRandomInt и BuildRandomChar.
⇑
3.3. Решение. Программа на языке C#. Приложение типа Console Application
Текст программы с решением задачи, следующий.
using System; namespace ConsoleApp9 { // 1. Классы, являющиеся продуктами // 1.1. ArrayRandomInt - массив случайных чисел class ArrayRandomInt { // Объявить внутреннюю переменную - экземпляр массива private int[] A; // Конструктор класса с тремя параметрами public ArrayRandomInt(int count, int min, int max) { // Создать экземпляр класса Random Random rndNum = new Random(); // Построить массив случайных чисел A = new int[count]; for (int i = 0; i < count; i++) { A[i] = rndNum.Next(min, max + 1); } } // Метод, возвращающий массив public int[] GetArrayInt() { return A; } } // 1.2. Массив символов от 'A' до 'Z' class ArrayRandomChar { // Массив случайных символов от 'A' до 'Z' private char[] A; public ArrayRandomChar(int count) { // Создать экземпляр класса Random Random rndChar = new Random(); // Построить массив A A = new char[count]; int t; for (int i = 0; i < count; i++) { // Получить случайный символ от 'A' до 'Z' A[i] = (char)(rndChar.Next((int)('Z' - 'A' + 1)) + (int)'A'); } } // Метод, возвращающий массив public char[] GetArrayChar() { return A; } } // 2. Класс, служащий интерфейсом с клиентом для генерирования объекта типа int class Builder { // В классе объявляются методы, предоставляемые классу-распорядителю virtual public void BuildArrayInt(int count, int min, int max) { } virtual public void BuildArrayChar(int count) { } // Методы, возвращающие конкретные объекты клиенту virtual public ArrayRandomInt GetResultInt() { return null; } virtual public ArrayRandomChar GetResultChar() { return null; } } // 3. Классы - строители экземпляров ArrayRandomInt и ArrayRandomChar class BuildRandomInt : Builder { private ArrayRandomInt A; override public void BuildArrayInt(int count, int min, int max) { // Построить экземпляр класса ArrayRandomInt A = new ArrayRandomInt(count, min, max); } override public ArrayRandomInt GetResultInt() { return A; } } class BuildRandomChar : Builder { private ArrayRandomChar A; public override void BuildArrayChar(int count) { A = new ArrayRandomChar(count); } public override ArrayRandomChar GetResultChar() { return A; } } // 4. Класс, выступающий распорядителем class Director { private Builder builder; // Конструктор класса public Director(Builder _builder) { builder = _builder; } // Метод, строящий массив случайных чисел public void ConstructInt() { // Построить массив из 10 целых чисел в диапазоне от 5 до 15 builder.BuildArrayInt(10, 5, 15); } public void ConstructChar() { // Построить массив из 15 символов типа char builder.BuildArrayChar(15); } } // Класс, выступающий клиентом class Program { static void Main(string[] args) { // Это клиент // 1. Генерирование объекта класса ArrayRandomInt // 1.1. Объявить продукт ArrayRandomInt AI; // Это результат - объект-массив целых чисел // 1.2. Объявить класс-строитель Builder BI = new BuildRandomInt(); // 1.3. Объявить распорядителя и сконфигурировать его конкретным строителем Director D = new Director(BI); D.ConstructInt(); // Построить объект-массив целых чисел // 1.4. Передать массив клиенту AI = BI.GetResultInt(); // 1.5. Проверить результат int[] arrInt = AI.GetArrayInt(); Console.WriteLine("Array AI:"); for (int i = 0; i < arrInt.Length; i++) Console.Write("{0} ", arrInt[i]); Console.WriteLine(); // ----------------------------------------- // 2. Генерирование объекта класса ArrayRandomChar // 2.1. Объявить продукт ArrayRandomChar AC; // 2.2. Объявить класс-строитель BuildRandomChar BC = new BuildRandomChar(); // 2.3. Объявить класс распорядитель и сформировать его строителем Director DC = new Director(BC); // 2.4. Построить массив значений типа char DC.ConstructChar(); // 2.5. Передать массив клиенту AC = BC.GetResultChar(); // 2.6. Вывести полученный массив для проверки char[] arrChar = AC.GetArrayChar(); Console.WriteLine("Array AC:"); for (int i = 0; i < arrChar.Length; i++) Console.Write("{0} ", arrChar[i]); Console.WriteLine(); } } }
⇑
3.4. Объяснение к программе
Как видно из рисунка 3, в программе используются два класса-строителя BuildRandomInt и BuildRandomChar, содержащие два метода построения объектов классов:
- метод BuildArrayInt() – создает экземпляр класса ArrayRandomInt;
- метод BuildArrayChar() — создает экземпляр класса ArrayRandomChar.
Классы ArrayRandomInt и ArrayRandomChar являются продуктами, которые передаются клиенту.
Класс Director является классом-распорядителем. В этом классе реализовано два метода ConstructInt() и ConstructChar(), из которых вызываются методы BuildArrayInt() и BuildArrayChar() с конкретными параметрами (длина массива, диапазон значений).
Класс Builder служит интерфейсом между классом-распорядителем Director и классами-строителями BuildRandomInt и BuildRandomChar.
Возможен был и другой вариант реализации задачи, в котором класс Builder был разбит на два подкласса, например BuilderInt и BuilderChar.
⇑
3.5. Результат выполнения программы
После запуска на выполнение программа выдаст следующий результат
Array AI: 5 10 14 7 5 11 10 8 9 14 Array AC: J M G N M S C H N L S Y E L V
⇑
Связанные темы
⇑