Sobes.tech
Middle

Wat is de implementatie van het abstracte fabriekspatroon?

sobes.tech AI

Antwoord van AI

Het Abstract Factory-patroon biedt een interface voor het creëren van families van onderling gerelateerde of afhankelijk objecten, zonder hun concrete klassen te specificeren.

Belangrijke componenten:

  1. Abstract Factory: Declareert een interface voor het creëren van abstracte producten.
  2. Concrete Factory: Implementeert de operaties voor het creëren van abstracte producten voor een specifiek productfamilie.
  3. Abstract Product: Declareert een interface voor het type product.
  4. Concrete Product: Implementeert de interface van Abstract Product voor een specifiek product.
  5. Client: Gebruikt de interfaces van Abstract Factory en Abstract Product, maar weet niet van Concrete Factory en Concrete Product.

Implementatie:

  • Een abstracte fabriek wordt gedefinieerd met methoden voor het creëren van elk type product.
  • Voor elke productfamilie wordt een concrete fabriek gemaakt die de methoden van de abstracte fabriek implementeert en de bijbehorende concrete producten creëert.
  • Voor elk type product wordt een abstracte interface gedefinieerd.
  • Voor elk concreet product wordt een klasse gemaakt die de overeenkomstige interface implementeert.
  • De client krijgt een object van de abstracte fabriek en roept haar methoden aan om producten te creëren, werkend met alleen de interfaces van de producten.
// Abstracte fabriek
public interface IAbstractFactory
{
    IAbstractProductA CreateProductA();
    IAbstractProductB CreateProductB();
}

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

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

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

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

// Abstract product A
public interface IAbstractProductA
{
    string UsefulFunctionA();
}

// Concrete product A1
public class ConcreteProductA1 : IAbstractProductA
{
    public string UsefulFunctionA()
    {
        return "The result of the product A1.";
    }
}

// Concrete product A2
public class ConcreteProductA2 : IAbstractProductA
{
    public string UsefulFunctionA()
    {
        return "The result of the product A2.";
    }
}

// Abstract product B
public interface IAbstractProductB
{
    string UsefulFunctionB();
    string AnotherUsefulFunctionB(IAbstractProductA collaborator);
}

// Concrete product B1
public class ConcreteProductB1 : IAbstractProductB
{
    public string UsefulFunctionB()
    {
        return "The result of the product B1.";
    }

    // Product B1 can only work with A products of the same variant
    public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
    {
        var result = collaborator.UsefulFunctionA();
        return $"The result of the B1 collaborating with the ({result})";
    }
}

// Concrete product B2
public class ConcreteProductB2 : IAbstractProductB
{
    public string UsefulFunctionB()
    {
        return "The result of the product B2.";
    }

    // Product B2 can only work with A products of the same variant
    public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
    {
        var result = collaborator.UsefulFunctionA();
        return $"The result of the B2 collaborating with the ({result})";
    }
}

// Client code
public class Client
{
    public void Main()
    {
        // Client code works with the abstract factory
        Console.WriteLine("Client: Testing client code with the first factory type:");
        ClientMethod(new ConcreteFactory1());
        Console.WriteLine();

        Console.WriteLine("Client: Testing the same client code with the second factory type:");
        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));
    }
}