Шаблон проектування “Фабричний метод” в C#

pic

Шаблони проектування є важливими інструментами в програмній інженерії, оскільки вони пропонують рішення для поширених проблем і сприяють використанню кращих практик. Серед цих шаблонів шаблон Factory Method виділяється своєю гнучкістю та креативними можливостями. Цей шаблон є частиною шаблонів проектування Gang of Four (GoF) та відноситься до створювальних шаблонів. У цій статті ми розглянемо шаблон Factory Method у C#, пояснимо його призначення, реалізацію та практичне використання.

Що таке шаблон Factory Method?

Шаблон Factory Method визначає інтерфейс для створення об'єкта, але дозволяє підкласам змінювати тип об'єктів, які будуть створюватися. Цей шаблон особливо корисний у ситуаціях, коли клас не може передбачити клас об'єктів, які йому потрібно створити, або коли клас хоче, щоб його підкласи визначали об'єкти, які він створює. Це забезпечує гнучкість і розв'язує процес створення об'єктів від їх фактичної реалізації, що робить його ідеальним для таких сценаріїв, як створення об'єктів у фреймворках або бібліотеках.

Основні характеристики

  • Створення на основі інтерфейсу: Визначає інтерфейс для створення об'єктів, дозволяючи підкласам вирішувати, який клас ініціалізувати.
  • Гнучкість: Забезпечує гнучкість, дозволяючи делегувати процес ініціалізації підкласам.
  • Розв'язування: Розв'язує код клієнта від конкретних класів об'єктів, які потрібно створити.

Реалізація

Розглянемо просту реалізацію системи видачі квитків, використовуючи шаблон Factory Method в C#.

public abstract class Ticket  
{  
 public string Departure;  
 public string Destination;  

 public Ticket(string departure, string destination)  
 {  
 Departure = departure;  
 Destination = destination;  
 }  

 public abstract void ShowDetails();  
}

Пояснення

  • Абстрактний клас: Ticket — це абстрактний клас, тобто його неможливо безпосередньо ініціалізувати. Натомість він служить як шаблон для своїх підкласів, забезпечуючи їх реалізацією методу ShowDetails.
  • Поля: Клас має два публічних поля, Departure та Destination, що зберігають місця відправлення та призначення квитка.
  • Абстрактний метод: ShowDetails — це абстрактний метод, що означає, що підкласи повинні надати свою реалізацію. Цей метод призначений для відображення деталей квитка, що забезпечує можливість кожному підкласу визначити свій власний спосіб відображення цих даних.

Ця структура дозволяє забезпечити гнучкість і гарантує, що кожен підклас Ticket надає конкретні деталі про тип квитка, який він представляє.

public class InterstateBusTicket : Ticket  
{  
 public InterstateBusTicket(string departure, string destination) : base(departure, destination)  
 {  
 }  

 public override void ShowDetails()  
 {  
 Console.WriteLine($"Interstate bus ticket: {Departure} to {Destination}.");  
 }  
}
public class UrbanBusTicket : Ticket  
{  
 public UrbanBusTicket(string departure, string destination) : base(departure, destination)  
 {  
 }  

 public override void ShowDetails()  
 {  
 Console.WriteLine($"Urban bus ticket: {Departure} to {Destination}.");  
 }  
}

Пояснення

  • Конкретні класи: InterstateBusTicket та UrbanBusTicket — це конкретні класи, які успадковують абстрактний клас Ticket. Вони надають конкретні реалізації для абстрактного методу ShowDetails, визначеного в Ticket.
  • Конструктори: Кожен клас має конструктор, який приймає місце відправлення та призначення як параметри. Ці конструктори використовують ключове слово base, щоб викликати конструктор класу Ticket, гарантуючи, що поля Departure та Destination будуть правильно ініціалізовані відповідно до логіки в класі Ticket.
  • Перевизначення методів: InterstateBusTicket перевизначає метод ShowDetails, щоб відобразити повідомлення, специфічне для міжміських автобусних квитків, використовуючи поля Departure та Destination для відображення маршруту.
    Точно так само, UrbanBusTicket перевизначає метод ShowDetails, щоб вивести повідомлення, орієнтоване на міські автобусні квитки, знову ж таки, використовуючи поля Departure та Destination для відображення маршруту подорожі.

Реалізація цих класів демонструє, як різні типи автобусних квитків можуть використовувати загальну структуру, надану класом Ticket, при цьому дозволяючи конкретну поведінку через перевизначення методів. Такий підхід сприяє повторному використанню коду та гнучкості, дозволяючи легко розширювати і змінювати типи квитків.

public abstract class Company  
{  
 public abstract Ticket IssueTicket(string departure, string destination);  
}

Пояснення

  • Абстрактний клас: Company — це абстрактний клас, тобто його неможливо безпосередньо ініціалізувати. Він служить шаблоном для своїх підкласів, гарантуючи, що ті реалізують метод IssueTicket.
  • Абстрактний метод: IssueTicket — це абстрактний метод, який приймає місце відправлення та призначення як параметри. Підкласи класу Company повинні надати конкретну реалізацію цього методу. Мета IssueTicket — визначити стандартний інтерфейс для видачі квитків, дозволяючи різним типам компаній реалізувати власну логіку створення квитків відповідно до своїх специфічних вимог.

Цей дизайн сприяє гнучкості та розширюваності, дозволяючи різним типам компаній видавати різні типи квитків, одночасно дотримуючись загального інтерфейсу, що полегшує додавання нових компаній чи типів квитків без зміни існуючої структури коду.

public class InterstateBusCompany : Company  
{  
 public override Ticket IssueTicket(string departure, string destination)  
 {  
 return new InterstateBusTicket(departure, destination);  
 }  
}
public class UrbanBusCompany : Company  
{  
 public override Ticket IssueTicket(string departure, string destination)  
 {  
 return new UrbanBusTicket(departure, destination);  
 }  
}

Пояснення

  • Конкретні класи: InterstateBusCompany та UrbanBusCompany — це конкретні класи, що успадковують абстрактний клас Company. Вони надають конкретні реалізації для абстрактного методу IssueTicket, визначеного в Company.
  • Перевизначення методів: У класі InterstateBusCompany метод IssueTicket перевизначено для створення та повернення екземпляра InterstateBusTicket, використовуючи надані параметри місця відправлення та призначення. Цей метод інкапсулює логіку видачі квитків, специфічну для міжміських автобусних поїздок. Точно так само UrbanBusCompany перевизначає метод IssueTicket для створення та повернення екземпляра UrbanBusTicket.

Ця реалізація демонструє, як різні типи компаній можуть використовувати спільний інтерфейс, одночасно налаштовуючи процес видачі квитків для задоволення своїх специфічних потреб. Такий підхід підвищує модульність і масштабованість, дозволяючи легко інтегрувати нові типи квитків чи компанії без порушення існуючої функціональності.

var urbanBus = new UrbanBusCompany();  
var interstateBus = new InterstateBusCompany();  

var urbanTicket = urbanBus.IssueTicket("Piccadilly Circus","Camden Town");  
var interstateTicket = interstateBus.IssueTicket("Los Angeles, CA","Las Vegas, NV");  

urbanTicket.ShowDetails();  
interstateTicket.ShowDetails();

Пояснення

  • Ініціалізація об'єктів: Створено два об'єкти, urbanBus та interstateBus, які є екземплярами класів UrbanBusCompany та InterstateBusCompany відповідно. Ці об'єкти представляють компанії, які можуть видавати різні типи автобусних квитків.
  • Видача квитків: urbanTicket створюється шляхом виклику методу IssueTicket на об'єкті urbanBus з параметрами “Piccadilly Circus” та “Camden Town”. Це призводить до створення екземпляра UrbanBusTicket для поїздки між цими двома локаціями. InterstateTicket створюється шляхом виклику методу IssueTicket на об'єкті interstateBus з параметрами “Los Angeles, CA” та “Las Vegas, NV”.
    Це призводить до створення екземпляра InterstateBusTicket для поїздки між цими двома містами.
  • Виведення деталей: викликається urbanTicket.ShowDetails(), що виводить повідомлення: "Міський автобусний квиток: Piccadilly Circus до Camden Town." Це повідомлення генерується перевизначеним методом ShowDetails класу UrbanBusTicket, вказуючи тип квитка та його маршрут. Далі викликається interstateTicket.ShowDetails(), що виводить повідомлення: "Міжміський автобусний квиток: Los Angeles, CA до Las Vegas, NV." Це повідомлення генерується перевизначеним методом ShowDetails класу InterstateBusTicket, також вказуючи тип квитка та маршрут.

pic

Виведення

Виведення відображає конкретні деталі квитків, які генеруються методами ShowDetails відповідних класів квитків, демонструючи універсальність шаблону Factory Method при обробці різних сценаріїв створення об'єктів, зберігаючи при цьому послідовний інтерфейс.

Висновок

Шаблон Factory Method є універсальним і корисним шаблоном проектування в C#, який дозволяє підкласам визначати, який клас ініціалізувати, сприяючи гнучкості та модульності. Відокремлюючи створення об'єктів від їх використання, цей шаблон дозволяє розробникам створювати розширювані та зручні для обслуговування структури коду. Розуміння та впровадження шаблону Factory Method може значно покращити вашу здатність ефективно керувати складними сценаріями створення об'єктів. Успіхів у програмуванні!

Якщо цей пост був корисним, будь ласка, поставте лайк і підписуйтесь на мене тут для більше контенту. Ви також можете підключитися до мене на LinkedIn.

Github Репозиторійhttps://github.com/Brunosalesb/design-patterns

Перекладено з: Factory Method Design Pattern in C#

Leave a Reply

Your email address will not be published. Required fields are marked *