C#: Фабричний метод

Factory Method Фабричний метод Factory Method

Фабричний метод — це породжуючий патерн проектування, який вирішує проблему створення різних продуктів, без прив'язки коду до конкретних класів продуктів.

Фабричний метод задає метод, який необхідно використовувати замість виклику оператора new для створення об'єктів-продуктів. Підкласи можуть перевизначити цей метод, щоб змінювати тип створюваних продуктів.

Якщо ви вже чули про Фабрику, Фабричний метод чи Абстрактну фабрику, але вам все одно важко їх розрізняти, то прочитайте нашу статтю Порівняння фабрик.

Детальніше про Фабричний метод

Особливості паттерна на C#

Складність:

Популярність:

Застосування: Патерн можна часто зустріти в будь-якому C#-коді, коли потрібна гнучкість при створенні продуктів.

Ознаки застосування патерну: Фабричний метод можна визначити за створюючими методами, які повертають об'єкти продуктів через абстрактні типи або інтерфейси. Це дозволяє змінювати типи створюваних продуктів у підкласах.

Приклад: Структура патерну

Цей приклад показує структуру патерну Фабричний метод, а саме — з яких класів він складається, які ролі ці класи виконують і як вони взаємодіють один з одним.

Program.cs: Приклад структури патерну

using System;

namespace RefactoringGuru.DesignPatterns.FactoryMethod.Structural
{
    abstract class Creator
    {
        public abstract IProduct FactoryMethod();

        public string SomeOperation()
        {
            var product = FactoryMethod();

            var result = "Creator: The same creator's code has just worked with " + product.Operation();

            return result;
        }
    }

    class ConcreteCreator1 : Creator
    {
        public override IProduct FactoryMethod()
        {
            return new ConcreteProduct1();
        }
    }

    class ConcreteCreator2 : Creator
    {
        public override IProduct FactoryMethod()
        {
            return new ConcreteProduct2();
        }
    }

    interface IProduct
    {
        string Operation();
    }

    class ConcreteProduct1 : IProduct
    {
        public string Operation()
        {
            return "{Result of ConcreteProduct1}";
        }
    }

    class ConcreteProduct2 : IProduct
    {
        public string Operation()
        {
            return "{Result of ConcreteProduct2}";
        }
    }

    class Client
    {
        public void Main()
        {
            Console.WriteLine("App: Launched with the ConcreteCreator1.");
            ClientMethod(new ConcreteCreator1());
            
            Console.WriteLine("");

            Console.WriteLine("App: Launched with the ConcreteCreator2.");
            ClientMethod(new ConcreteCreator2());
        }

        public void ClientMethod(Creator creator)
        {
            // ...
            Console.WriteLine("Client: I'm not aware of the creator's class, but it still works.\n"
                              + creator.SomeOperation());
            // ...
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            new Client().Main();
        }
    }
}

Output.txt: Результат виконання

App: Launched with the ConcreteCreator1.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of ConcreteProduct1}

App: Launched with the ConcreteCreator2.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of ConcreteProduct2}