Método de fábrica C#

Resumo : neste tutorial, você aprenderá sobre o padrão de design do método de fábrica C# e como usá-lo para criar objetos sem acoplar fortemente o código de criação do objeto ao código do cliente.

Introdução ao padrão de design do método de fábrica C#

Uma fábrica do mundo real produz produtos. Na programação, uma fábrica cria objetos. Quando um método cria e retorna um objeto, ele é chamado de método de fábrica.

O padrão Factory Method é um padrão de design criacional, que fornece uma interface para criar objetos em uma superclasse, mas permite que as subclasses decidam o tipo de objeto.

O diagrama UML a seguir ilustra o padrão Factory Method:

Padrão de design do método de fábrica C#

O padrão Factory Method consiste nos seguintes participantes:

  • Creator: a classe abstrata que define um método de fábrica para criar objetos. Pode creatorser uma interface se não tiver uma implementação compartilhada com as subclasses.
  • Product: a classe abstrata que define a interface para os objetos criados pelo método de fábrica. Assim como o Creator, o Productpode ser uma interface.
  • ConcreteFactory: a classe concreta que herda da Creatorclasse. A ConcreteFactoryclasse cria ConcreateProductque herda do Product.
  • ConcreteProduct: a classe concreta que estende a Productclasse.

Aqui está a implementação do padrão de método de fábrica em C#:

namespace FactoryMethod;

public abstract class Product {}

public abstract class Creator
{
    public abstract Product FactoryMethod();

    public void Operation()
    {
        var product = FactoryMethod();
        
        // process the product
        // ...
        Console.WriteLine($"Work with the {product}");
    }
}

public class ConcreateProduct: Product {}

public class ConcreteFactory : Creator
{
    public override Product FactoryMethod() => new ConcreateProduct();
}

public class Program
{
    public static void Main(string[] args)
    {
        var creator = new ConcreteCreator();
        creator.Operation();
    }
}Linguagem de código:  C#  ( cs )

Saída:

Work with the FactoryMethod.ConcreateProductLinguagem de código:  JavaScript  ( javascript )

Padrão de método de fábrica versus a nova palavra-chave

1) A palavra-chave new cria dependências entre o código do cliente e as implementações concretas das classes

Ao usar a newpalavra-chave para criar objetos de classes, você cria dependências entre o código do cliente e a implementação concreta das classes.

Se as classes mudarem, você deverá alterar o código do cliente para acomodar a nova implementação. Isso torna seu código fortemente acoplado e difícil de estender.

O padrão Factory Method separa o código do cliente da implementação dos objetos que estão sendo criados.

O código do cliente só precisa conhecer a interface de fábrica, que fornece uma maneira de criar objetos sem conhecer a implementação específica dos objetos que cria.

Portanto, o método de fábrica torna seu código mais flexível, testável e mais fácil de estender.

2) A nova palavra-chave dificulta a troca de implementações

A newpalavra-chave também dificulta a troca de implementações. Se você introduziu uma nova implementação ou substituiu uma existente, será necessário atualizar o código do cliente. Isto viola o princípio aberto-fechado .

Por outro lado, usar o Factory Method facilita a troca de implementações sem a necessidade de modificar o código do cliente.

A razão é que o código do cliente só precisa conhecer a interface de fábrica e pode utilizá-la para criar objetos sem conhecer a implementação específica que está sendo utilizada.

Exemplo de padrão de design do método de fábrica C#

O programa a seguir demonstra como usar o padrão Factory Method para implementar uma política de descontos para um sistema de pedidos simplificado:

namespace FactoryMethod;

public abstract class Discount
{
    public abstract decimal GetPercentage();
}
public class RegularDiscount : Discount
{
    public override decimal GetPercentage() => 0.1m;
}
public class IrregularDiscount : Discount
{
    public override decimal GetPercentage() => 0.15m;
}

public abstract class DiscountPolicy
{
    public abstract Discount Create();

    public decimal Apply(decimal Price)
    {
        var discount = Create();
        return Price * (1 - discount.GetPercentage());
    }

}

public class RegularDiscountPolicy : DiscountPolicy
{
    public override Discount Create() => new RegularDiscount();
}


public class IrregularDiscountPolicy : DiscountPolicy
{
    public override Discount Create() => new IrregularDiscount();
}

public class Order
{
    private readonly decimal _netAmount;
    public decimal Amount => OrderDiscountPolicy.Apply(_netAmount);
    public DiscountPolicy OrderDiscountPolicy
    {
        get; private set;
    }
    public Order(decimal amount, DiscountPolicy discountPolicy)
    {
        _netAmount = amount;
        OrderDiscountPolicy = discountPolicy;
    }
}

public class Program
{
    public static void Main()
    {
        var order = new Order(1000, new IrregularDiscountPolicy());
        Console.WriteLine(order.Amount);
    }
}Linguagem de código:  C#  ( cs )

Saída:

850.00Linguagem de código:  CSS  ( css )

Como funciona.

O diagrama UML a seguir ilustra como funcionam os relacionamentos entre as classes no programa:

Exemplo de padrão de design de método de fábrica C#

Primeiro, defina DiscountPolicy como uma classe abstrata. A classe DiscountPolicy possui o método Create() que cria e retorna um novo objeto Discount.

A seguir, defina as classes RegularDiscountPolicye IrregularDiscountPolicyque estendem a DiscountPolicyclasse. O Create()método dessas classes retorna a RegularDiscounte IrregularDiscountobject, respectivamente.

Em seguida, defina a Discountclasse como uma classe abstrata. A Discountclasse tem duas classes concretas, incluindo classes RegularDiscounte IrregularDiscount.

Depois disso, defina a Orderclasse que utiliza a DiscountPolicyclasse. A Orderclasse armazena um valor líquido do pedido e uma política de desconto. A Amountpropriedade devolve o valor após aplicar a política de desconto ao valor líquido.

Por fim, crie um Orderobjeto com valor líquido 1000e um IrregularDiscountPolicyobjeto no Main()método da Programclasse e exiba o valor após aplicar a política de desconto no console.

Neste exemplo, você pode trocar a política de desconto de para IrregularDiscountPolicysem RegularDiscountPolicymodificar a Orderclasse.

Além disso, você pode introduzir uma nova política de descontos, por exemplo, SpecialDiscountPolicye trocá-la pela política de descontos atual sem alterar a Orderclasse.

Resumo

  • Use o padrão de design Factory Method para criar objetos sem acoplar fortemente o código de criação do objeto ao código do cliente.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *