Sobes.tech
Middle

Какво е реализирането на патърна абстрактна фабрика?

sobes.tech AI

Отговор от AI

Моделът Abstract Factory предоставя интерфейс за създаване на семейства от взаимосвързани или зависими обекти, без да специфицира конкретните им класове.

Основни компоненти:

  1. Abstract Factory: Обявява интерфейс за операциите по създаване на абстрактни продукти.
  2. Concrete Factory: Реализира операциите по създаване на абстрактни продукти за конкретно семейство продукти.
  3. Abstract Product: Обявява интерфейс за типа продукт.
  4. Concrete Product: Реализира интерфейса на Abstract Product за конкретен продукт.
  5. Client: Използва интерфейсите на Abstract Factory и Abstract Product, но не знае за Concrete Factory и Concrete Product.

Имплементация:

  • Определя се абстрактна фабрика с методи за създаване на всеки тип продукт.
  • За всяко семейство продукти се създава конкретна фабрика, която реализира методите на абстрактната фабрика и създава съответните конкретни продукти.
  • За всеки тип продукт се определя абстрактен интерфейс.
  • За всеки конкретен продукт се създава клас, който реализира съответния интерфейс.
  • Клиентският код получава обект на абстрактната фабрика и извиква нейните методи за създаване на продукти, работейки само с интерфейсите на продуктите.
// Абстрактна фабрика
public interface IAbstractFactory
{
    IAbstractProductA CreateProductA();
    IAbstractProductB CreateProductB();
}

// Конкретна фабрика 1
public class ConcreteFactory1 : IAbstractFactory
{
    public IAbstractProductA CreateProductA()
    {
        return new ConcreteProductA1();
    }

    public IAbstractProductB CreateProductB()
    {
        return new ConcreteProductB1();
    }
}

// Конкретна фабрика 2
public class ConcreteFactory2 : IAbstractFactory
{
    public IAbstractProductA CreateProductA()
    {
        return new ConcreteProductA2();
    }

    public IAbstractProductB CreateProductB()
    {
        return new ConcreteProductB2();
    }
}

// Абстрактен продукт A
public interface IAbstractProductA
{
    string UsefulFunctionA();
}

// Конкретен продукт A1
public class ConcreteProductA1 : IAbstractProductA
{
    public string UsefulFunctionA()
    {
        return "Резултатът от продукта A1.";
    }
}

// Конкретен продукт A2
public class ConcreteProductA2 : IAbstractProductA
{
    public string UsefulFunctionA()
    {
        return "Резултатът от продукта A2.";
    }
}

// Абстрактен продукт B
public interface IAbstractProductB
{
    string UsefulFunctionB();
    string AnotherUsefulFunctionB(IAbstractProductA collaborator);
}

// Конкретен продукт B1
public class ConcreteProductB1 : IAbstractProductB
{
    public string UsefulFunctionB()
    {
        return "Резултатът от продукта B1.";
    }

    // Продукт B1 може да работи само с продукти A от същия вариант
    public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
    {
        var result = collaborator.UsefulFunctionA();
        return $"Резултатът на B1, работещ с ({result})";
    }
}

// Конкретен продукт B2
public class ConcreteProductB2 : IAbstractProductB
{
    public string UsefulFunctionB()
    {
        return "Резултатът от продукта B2.";
    }

    // Продукт B2 може да работи само с продукти A от същия вариант
    public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
    {
        var result = collaborator.UsefulFunctionA();
        return $"Резултатът на B2, работещ с ({result})";
    }
}

// Клиентски код
public class Client
{
    public void Main()
    {
        // Клиентският код работи с абстрактната фабрика
        Console.WriteLine("Клиент: Тестиране на клиентския код с първия тип фабрика:");
        ClientMethod(new ConcreteFactory1());
        Console.WriteLine();

        Console.WriteLine("Клиент: Тестиране на същия клиентски код с втория тип фабрика:");
        ClientMethod(new ConcreteFactory2());
    }

    public void ClientMethod(IAbstractFactory factory)
    {
        var productA = factory.CreateProductA();
        var productB = factory.CreateProductB();

        Console.WriteLine(productB.UsefulFunctionB());
        Console.WriteLine(productB.AnotherUsefulFunctionB(productA));
    }
}