Шаблони проектування є основними інструментами в розробці програмного забезпечення, які надають стандартизовані рішення для повторюваних проблем і сприяють впровадженню найкращих практик у проектуванні. Серед цих шаблонів особливо виділяється шаблон Builder завдяки своїй здатності будувати складні об'єкти поетапно, дозволяючи чітко розділяти процес побудови та представлення об'єкта. Як один із креативних шаблонів проектування, визнаних Gang of Four (GoF), шаблон Builder пропонує потужну структуру для керування створенням об'єктів гнучким і контрольованим способом. У цій статті ми розглянемо шаблон проектування Builder, детально описавши його мету та практичне застосування.
Що таке шаблон проектування Builder?
Шаблон Builder надає інтерфейс для побудови складних об'єктів поетапно, дозволяючи створювати різні представлення об'єкта, використовуючи той самий процес побудови. Цей шаблон особливо корисний у ситуаціях, коли створення об'єкта вимагає кількох кроків і може змінюватися відповідно до різних вимог. Використовуючи шаблон Builder, розробники можуть забезпечити чіткість і керованість свого коду, оскільки він розділяє логіку побудови від представлення, що полегшує створення різноманітних і складних об'єктів.
Основні характеристики
- Поетапна побудова: Шаблон Builder розбиває створення складного об'єкта на ряд окремих кроків, дозволяючи більш точно контролювати процес побудови та створювати різні представлення об'єкта.
- Повторне використання та гнучкість: Інкапсулюючи логіку побудови, шаблон Builder дозволяє повторно використовувати процес побудови для створення різних типів об'єктів. Це підвищує гнучкість, дозволяючи створювати різні конфігурації або версії продукту без змін у клієнтському коді.
- Розділення обов'язків: Шаблон розділяє побудову об'єкта від його представлення, що сприяє чіткій та зручній архітектурі. Це розділення дозволяє розробникам зосередитися на поетапному процесі створення, незалежно від того, як буде використовуватись або представлене кінцеве об'єкт.
Реалізація
Розглянемо просту реалізацію системи приготування їжі, використовуючи шаблон проектування Builder у C#.
public abstract class Sandwich
{
}
Пояснення
- Sandwich: Цей абстрактний клас слугує шаблоном для своїх підкласів, гарантуючи, що кожен тип сендвіча (наприклад, Hamburger і FishBurger) є похідним від цього базового класу. Абстрактний клас надає загальну структуру для всіх типів сендвічів, сприяючи організації коду та повторному використанню.
public class FishBurger : Sandwich
{
}
public class Hamburger : Sandwich
{
}
Пояснення
- Наслідування та мета: Обидва класи Hamburger та FishBurger наслідують від абстрактного класу Sandwich. Вони слугують конкретними реалізаціями різних типів сендвічів, використовуючи структуру, надану класом Sandwich.
- Налаштування: Хоча ці класи наразі порожні, їх можна розширити для включення властивостей і методів, специфічних для кожного типу. Це дозволяє кожному типу сендвіча мати свої унікальні характеристики та поведінку, забезпечуючи гнучкість і масштабованість системи.
Ця структура сприяє гнучкій та масштабованій архітектурі, дозволяючи легко додавати нові типи сендвічів, просто розширюючи клас Sandwich.
Кожен конкретний тип може мати свої унікальні властивості та поведінку, зберігаючи при цьому єдиний інтерфейс.
public abstract class SandwichBuilder
{
public abstract void OpenBread();
public abstract void AddIngredients();
public abstract void CloseBread();
public abstract Sandwich GetSandwich();
}
Пояснення
- SandwichBuilder: Це абстрактний клас, який визначає шаблон для побудови різних типів сендвічів. Він описує необхідні кроки у процесі приготування сендвіча, але не надає реалізації для цих кроків. Замість цього він визначає набір абстрактних методів, які повинні бути реалізовані в підкласах. Це гарантує єдиний інтерфейс для створення сендвічів, незалежно від конкретного типу.
- Абстрактні методи: Абстрактні методи визначають основні кроки для створення сендвіча. Кожен метод вимагає від підкласів реалізувати конкретні деталі: OpenBread() готує хліб до наповнення, AddIngredients() визначає інгредієнти та їх розташування, CloseBread() завершить збірку сендвіча, а GetSandwich() повертає готовий об'єкт сендвіча. Цей підхід гарантує, що кожен тип сендвіча слідує єдиному процесу створення, при цьому дозволяючи налаштування та варіативність в реалізації кожного кроку.
public class HamburgerBuilder : SandwichBuilder
{
private Sandwich _sandwich = new Hamburger();
public override void OpenBread()
{
Console.WriteLine("Open Bread");
}
public override void AddIngredients()
{
Console.WriteLine("Add Ingredients");
}
public override void CloseBread()
{
Console.WriteLine("Close Bread");
}
public override Sandwich GetSandwich()
{
Console.WriteLine("Hamburger Done!");
return _sandwich;
}
}
public class FishBuilder : SandwichBuilder
{
private Sandwich _sandwich = new FishBurger();
public override void OpenBread()
{
Console.WriteLine("Open Bread");
}
public override void AddIngredients()
{
Console.WriteLine("Add Ingredients");
}
public override void CloseBread()
{
Console.WriteLine("Close Bread");
}
public override Sandwich GetSandwich()
{
Console.WriteLine("Fish Burger Done!");
return _sandwich;
}
}
Пояснення
- Наслідування та мета: Обидва класи наслідують абстрактний клас SandwichBuilder, що гарантує їх реалізацію єдиного інтерфейсу для створення сендвічів. Їх мета - надати конкретні реалізації для створення гамбургерів та рибних сендвічів, слідуючи визначеним крокам створення.
- Приватні поля: Кожен клас зберігає приватне поле, _sandwich, яке утримує екземпляр конкретного типу сендвіча, за який він відповідає. У HamburgerBuilder це екземпляр класу Hamburger, а у FishBuilder — екземпляр класу FishBurger.
- Реалізація методів: В обох класах метод OpenBread() виводить “Open Bread”, щоб сигналізувати про початок приготування сендвіча, AddIngredients() виводить “Add Ingredients”, щоб відобразити додавання конкретних інгредієнтів для кожного типу сендвіча. Метод CloseBread() виводить “Close Bread”, що позначає фінальний етап складання сендвіча.
Нарешті, метод GetSandwich() виводить повідомлення про завершення (“Hamburger Done!” або “Fish Burger Done!”) і повертає відповідний екземпляр сендвіча, або Hamburger, або FishBurger.
Реалізуючи ці методи, обидва класи демонструють гнучкість та розширюваність шаблону Builder, дозволяючи створювати різні типи сендвічів, зберігаючи єдиний процес створення.
public class Kitchen
{
public void CreateSandwich(SandwichBuilder builder){
builder.OpenBread();
builder.AddIngredients();
builder.CloseBread();
}
}
Пояснення
- Мета класу: Клас Kitchen виступає як директор у шаблоні Builder, координуючи процес створення сендвіча.
- Метод: Метод CreateSandwich() приймає об'єкт SandwichBuilder як параметр і по черзі викликає методи OpenBread(), AddIngredients() і CloseBread() на будівельнику.
- Функціональність: Керує послідовністю створення без втручання в специфіку кожного типу сендвіча, що обробляється конкретними класами будівельників.
Цей підхід дозволяє зберігати гнучкість і масштабованість, дозволяючи додавати нові типи сендвічів просто додавши нові класи будівельників, забезпечуючи єдину і розширювану структуру.
Kitchen kitchen = new Kitchen();
SandwichBuilder b1 = new HamburgerBuilder();
SandwichBuilder b2 = new FishBuilder();
kitchen.CreateSandwich(b1);
b1.GetSandwich();
kitchen.CreateSandwich(b2);
b2.GetSandwich();
Пояснення
- Ініціалізація Kitchen: Об'єкт Kitchen створюється як директор, який управляє процесом створення сендвіча.
- Ініціалізація Builder: HamburgerBuilder(b1) створюється як екземпляр HamburgerBuilder, відповідальний за створення гамбургерів. FishBuilder(b2) створюється як екземпляр FishBuilder, відповідальний за створення рибних сендвічів.
- Створення гамбургера: Кухня використовує метод CreateSandwich() з b1, виконуючи кроки, необхідні для приготування гамбургера. Після створення викликається b1.GetSandwich() для отримання і фіналізації гамбургера, що завершує процес.
- Створення рибного сендвіча: Потім кухня використовує метод CreateSandwich() з b2, виконуючи кроки для приготування рибного сендвіча. Викликається b2.GetSandwich() для отримання і фіналізації рибного сендвіча, що завершує процес.
Цей код демонструє гнучкість шаблону Builder, дозволяючи безперешкодно створювати різні типи сендвічів без модифікації логіки директора. Цей підхід підтримує легку розширюваність, де нові типи сендвічів можна додавати шляхом додавання нових класів будівельників.
Виведення показує стандартизовані кроки — Open Bread, Add Ingredients, Close Bread — що використовуються для створення як гамбургера, так і рибного сендвіча, завершуючи підтвердженнями: “Hamburger Done!” та “Fish Burger Done!”.
Висновок
Шаблон проектування Builder, як показано в цій статті, є високоефективним шаблоном проектування в C#, який дозволяє будувати складні об'єкти поетапно, відокремлюючи процес створення від кінцевого представлення. Цей шаблон підвищує гнучкість, дозволяючи створювати різні представлення об'єктів, використовуючи єдиний процес побудови. Відокремлюючи створення об'єкта від його представлення, шаблон Builder сприяє створенню модульного та підтримуваного коду, дозволяючи розробникам легко розширювати та адаптувати свої програми до нових вимог. Оволодіння шаблоном проектування Builder значно покращить вашу здатність ефективно управляти складними сценаріями створення об'єктів з ясністю та точністю. Щасливого кодування!
Якщо ця стаття була корисною, будь ласка, поставте “лайк” і підпишіться на мене тут для нових матеріалів.
Ви також можете зв'язатися зі мною через LinkedIn.
Репозиторій на Github — https://github.com/Brunosalesb/design-patterns
Перекладено з: Builder Design Pattern in C#