Sobes.tech
Middle

Na czym polega implementacja wzorca fabryki abstrakcyjnej?

sobes.tech AI

Odpowiedź od AI

Wzorzec Abstract Factory zapewnia interfejs do tworzenia rodzin powiązanych lub zależnych od siebie obiektów, nie precyzując ich konkretnych klas.

Główne komponenty:

  1. Abstract Factory: Deklaruje interfejs dla operacji tworzenia produktów abstrakcyjnych.
  2. Concrete Factory: Implementuje operacje tworzenia produktów abstrakcyjnych dla konkretnej rodziny produktów.
  3. Abstract Product: Deklaruje interfejs dla typu produktu.
  4. Concrete Product: Implementuje interfejs produktu abstrakcyjnego dla konkretnego produktu.
  5. Client: Używa interfejsów Abstract Factory i Abstract Product, ale nie zna Concrete Factory ani Concrete Product.

Implementacja:

  • Definiuje się abstrakcyjną fabrykę z metodami do tworzenia każdego typu produktu.
  • Dla każdej rodziny produktów tworzy się konkretną fabrykę, implementującą metody abstrakcyjnej fabryki i tworzącą odpowiednie konkretne produkty.
  • Dla każdego typu produktu definiuje się interfejs produktu abstrakcyjnego.
  • Dla każdego konkretnego produktu tworzy się klasę implementującą odpowiedni interfejs.
  • Część klienta uzyskuje obiekt abstrakcyjnej fabryki i wywołuje jej metody do tworzenia produktów, pracując tylko z interfejsami produktów.
// Abstrakcyjna fabryka
public interface IAbstractFactory
{
    IAbstractProductA CreateProductA();
    IAbstractProductB CreateProductB();
}

// Konkretny fabryka 1
public class ConcreteFactory1 : IAbstractFactory
{
    public IAbstractProductA CreateProductA()
    {
        return new ConcreteProductA1();
    }

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

// Konkretny fabryka 2
public class ConcreteFactory2 : IAbstractFactory
{
    public IAbstractProductA CreateProductA()
    {
        return new ConcreteProductA2();
    }

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

// Abstrakcyjny produkt A
public interface IAbstractProductA
{
    string UsefulFunctionA();
}

// Konkretny produkt A1
public class ConcreteProductA1 : IAbstractProductA
{
    public string UsefulFunctionA()
    {
        return "Wynik produktu A1.";
    }
}

// Konkretny produkt A2
public class ConcreteProductA2 : IAbstractProductA
{
    public string UsefulFunctionA()
    {
        return "Wynik produktu A2.";
    }
}

// Abstrakcyjny produkt B
public interface IAbstractProductB
{
    string UsefulFunctionB();
    string AnotherUsefulFunctionB(IAbstractProductA collaborator);
}

// Konkretny produkt B1
public class ConcreteProductB1 : IAbstractProductB
{
    public string UsefulFunctionB()
    {
        return "Wynik produktu B1.";
    }

    // Produkt B1 może współpracować tylko z produktami A tego samego wariantu
    public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
    {
        var result = collaborator.UsefulFunctionA();
        return $"Wynik B1 współpracującego z ({result})";
    }
}

// Konkretny produkt B2
public class ConcreteProductB2 : IAbstractProductB
{
    public string UsefulFunctionB()
    {
        return "Wynik produktu B2.";
    }

    // Produkt B2 może współpracować tylko z produktami A tego samego wariantu
    public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
    {
        var result = collaborator.UsefulFunctionA();
        return $"Wynik B2 współpracującego z ({result})";
    }
}

// Kod klienta
public class Client
{
    public void Main()
    {
        // Kod klienta pracuje z abstrakcyjną fabryką
        Console.WriteLine("Klient: Testowanie kodu klienta z pierwszym typem fabryki:");
        ClientMethod(new ConcreteFactory1());
        Console.WriteLine();

        Console.WriteLine("Klient: Testowanie tego samego kodu klienta z drugim typem fabryki:");
        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));
    }
}