Sobes.tech
Middle

Qual é a implementação do padrão de fábrica abstrata?

sobes.tech IA

Resposta da IA

O padrão Abstract Factory fornece uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.

Componentes principais:

  1. Abstract Factory: Declara a interface para as operações de criação de produtos abstratos.
  2. Concrete Factory: Implementa as operações de criação de produtos abstratos para uma família concreta de produtos.
  3. Abstract Product: Declara a interface para um tipo de produto.
  4. Concrete Product: Implementa a interface do produto abstrato para um produto concreto.
  5. Client: Usa as interfaces de Abstract Factory e Abstract Product, mas não conhece a Concrete Factory nem a Concrete Product.

Implementação:

  • Definir uma fábrica abstrata com métodos para criar cada tipo de produto.
  • Para cada família de produtos, criar uma fábrica concreta que implementa os métodos de fábrica abstrata e cria os produtos concretos correspondentes.
  • Para cada tipo de produto, definir uma interface de produto abstrato.
  • Para cada produto concreto, criar uma classe que implementa a interface correspondente.
  • A parte cliente obtém um objeto da fábrica abstrata e chama seus métodos para criar produtos, trabalhando apenas com as interfaces dos produtos.
// Fábrica abstrata
public interface IAbstractFactory
{
    IAbstractProductA CreateProductA();
    IAbstractProductB CreateProductB();
}

// Fábrica concreta 1
public class ConcreteFactory1 : IAbstractFactory
{
    public IAbstractProductA CreateProductA()
    {
        return new ConcreteProductA1();
    }

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

// Fábrica concreta 2
public class ConcreteFactory2 : IAbstractFactory
{
    public IAbstractProductA CreateProductA()
    {
        return new ConcreteProductA2();
    }

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

// Produto abstrato A
public interface IAbstractProductA
{
    string UsefulFunctionA();
}

// Produto concreto A1
public class ConcreteProductA1 : IAbstractProductA
{
    public string UsefulFunctionA()
    {
        return "O resultado do produto A1.";
    }
}

// Produto concreto A2
public class ConcreteProductA2 : IAbstractProductA
{
    public string UsefulFunctionA()
    {
        return "O resultado do produto A2.";
    }
}

// Produto abstrato B
public interface IAbstractProductB
{
    string UsefulFunctionB();
    string AnotherUsefulFunctionB(IAbstractProductA collaborator);
}

// Produto concreto B1
public class ConcreteProductB1 : IAbstractProductB
{
    public string UsefulFunctionB()
    {
        return "O resultado do produto B1.";
    }

    // O produto B1 só pode trabalhar com produtos A do mesmo tipo
    public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
    {
        var result = collaborator.UsefulFunctionA();
        return $"O resultado do B1 colaborando com o ({result})";
    }
}

// Produto concreto B2
public class ConcreteProductB2 : IAbstractProductB
{
    public string UsefulFunctionB()
    {
        return "O resultado do produto B2.";
    }

    // O produto B2 só pode trabalhar com produtos A do mesmo tipo
    public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
    {
        var result = collaborator.UsefulFunctionA();
        return $"O resultado do B2 colaborando com o ({result})";
    }
}

// Código cliente
public class Client
{
    public void Main()
    {
        // O código cliente trabalha com a fábrica abstrata
        Console.WriteLine("Cliente: Testando código cliente com o primeiro tipo de fábrica:");
        ClientMethod(new ConcreteFactory1());
        Console.WriteLine();

        Console.WriteLine("Cliente: Testando o mesmo código cliente com o segundo tipo de fábrica:");
        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));
    }
}