Padrão de adaptador C#

Resumo : neste tutorial, você aprenderá como usar o padrão C# Adapter para permitir que classes de interfaces incompatíveis trabalhem juntas.

Introdução ao padrão C# Adapter

O padrão Adapter converte uma interface em outra interface que os clientes esperam. O padrão Adapter permite que classes de interfaces incompatíveis trabalhem juntas.

Suponha que você esteja viajando para um país estrangeiro e queira carregar seu telefone. O problema é que a tomada elétrica naquele país tem um formato diferente do plugue do carregador do seu telefone.

Para resolver esse problema, você pode usar um adaptador que converte a tomada externa no formato de plugue do carregador do telefone.

Este adaptador serve como um invólucro que traduz a interface do soquete externo na interface que o carregador do seu telefone espera. Ao fazer isso, você pode carregar seu telefone sem alterar a tomada externa.

Padrão de adaptador C#

Da mesma forma, o padrão Adapter cria um adaptador que converte a interface de um objeto em uma interface que os clientes esperam, permitindo que trabalhem juntos sem modificar seu código.

O padrão Adapter possui duas variantes: adaptador de objeto e adaptador de classe.

Adaptador de objeto

O diagrama UML a seguir ilustra o adaptador de objeto:

Padrão de adaptador de objeto C#

Neste diagrama UML do adaptador de objeto:

  • ITargetinterface: Esta é a interface com a qual o cliente espera trabalhar. É também a interface que a Adapterclasse implementará.
  • Adaptee: é a classe que possui uma interface que não é compatível com a ITargetinterface. É a classe que a Adapterclasse irá embrulhar e adaptar.
  • Adapter: é a classe que implementa a interface de destino e envolve o Adapteeobjeto. A Adapterclasse é responsável por traduzir as chamadas da ITargetinterface para a Adapteeinterface do e delegar o trabalho a ela.

Neste padrão, o Adapterpossui um membro que é o Adapteeobjeto. O Operation()método da Adapterclasse chama o SpecificOperation()método do Adapteeobjeto.

Exemplo de adaptador de objeto

Suponha que você precise implementar um recurso de pagamento em seu aplicativo de sistema. E você precisa usar uma classe de terceiros chamada PaymentProcessor.

A PaymentProcessorclasse possui um método chamado ProcessPayment, que aceita um decimalargumento que representa o valor do pagamento:

public class PaymentProcessor
{
    public void ProcessPayment(decimal amount)
    {
        Console.WriteLine($"You have paid {amount:C}.");
    }
}Linguagem de código:  C#  ( cs )

Mas seu aplicativo usa uma interface chamada IPaymentProvidercom um método MakePayment. O problema é que o MakePaymentmétodo aceita dois argumentos: uma string que representa os detalhes do pagamento e um valor decimal que representa o valor do pagamento:

public interface IPaymentProvider
{
    void MakePayment(string details, decimal amount);
}Linguagem de código:  C#  ( cs )

Como você pode ver, a interface que seu aplicativo espera é IPaymentProviderincompatível com a classe PaymentProcessor.

Para resolver esse problema, você pode aplicar o padrão Adaptador de objeto.

Para usar o PaymentProcessorcom sua IPaymentProviderinterface, você pode criar uma Adapterclasse chamada PaymentProviderAdapter.

As PaymentProviderAdapternecessidades de implementar a IPaymentProviderinterface e agrupar a PaymentProcessorclasse. Além disso, o MakePaymentmétodo precisa PaymnetProviderAdaptertraduzir a chamada para o ProcessPaymentmétodo da PaymentProcessorclasse:

// The adapter class that adapts the PaymentProcessor
// to the IPaymentProvider interface
public class PaymentProviderAdapter : IPaymentProvider
{
    private readonly PaymentProcessor _paymentProcessor;

    public PaymentProviderAdapter(PaymentProcessor paymentProcessor)
    {
        _paymentProcessor = paymentProcessor;
    }

    public void MakePayment(string details, decimal amount)
    {
        Console.WriteLine($"Making a payment for: {details}");
        _paymentProcessor.ProcessPayment(amount);
    }
}Linguagem de código:  C#  ( cs )

Agora, você pode usar a PaymentProcessorclasse em seu aplicativo da seguinte maneira:

public class Program
{
    public static void Main(string[] args)
    {
        var paymentProcessor = new PaymentProcessor();
        var paymentProvider = new PaymentProviderAdapter(paymentProcessor);

        paymentProvider.MakePayment("C# design pattern course", 100.0m);
    }
}Linguagem de código:  C#  ( cs )

Na Programaula:

  • Primeiro, crie uma instância da PaymentProcessclasse e crie uma instância da PaymentProviderAdapterclasse que envolve o PaymentProcessobjeto ‘s.
  • Segundo, chame o método MakePaymentda instância da PaymentProviderAdapterclasse para efetuar um pagamento, que por sua vez chamará o ProcessPaymentmétodo da PaymentProcessorclasse.

Junte tudo.

namespace ObjectAdapter;

// The third-party PaymentProcessor class
public class PaymentProcessor
{
    public void ProcessPayment(decimal amount)
    {
        Console.WriteLine($"You have paid {amount:C}.");
    }
}

// your application's IPaymentProvider interface
public interface IPaymentProvider
{
    void MakePayment(string details, decimal amount);
}

// The adapter class that adapts the PaymentProcessor
// to the IPaymentProvider interface
public class PaymentProviderAdapter : IPaymentProvider
{
    private readonly PaymentProcessor _paymentProcessor;

    public PaymentProviderAdapter(PaymentProcessor paymentProcessor)
    {
        _paymentProcessor = paymentProcessor;
    }

    public void MakePayment(string details, decimal amount)
    {
        Console.WriteLine($"Making a payment for: {details}");
        _paymentProcessor.ProcessPayment(amount);
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        var paymentProcessor = new PaymentProcessor();
        var paymentProvider = new PaymentProviderAdapter(paymentProcessor);

        paymentProvider.MakePayment("C# design pattern course", 100.0m);
    }
}Linguagem de código:  C#  ( cs )

Saída:

Making a payment for: C# design pattern course
You have paid $100.00.Linguagem de código:  C#  ( cs )

Padrão de adaptador de classe

O padrão Object Adapter usa composição para agrupar a classe incompatível. Enquanto isso, o padrão da classe Adapter usa herança .

No padrão Class Adapter, a Adapterclasse estende as Adapteeclasses e as classes de destino. A Adapterclasse então substitui o método da classe de destino e chama o método correspondente da Adapteeinterface.

C# não oferece suporte a múltiplas heranças que permitem que uma classe estenda duas ou mais classes. Porém, uma classe pode estender uma classe e implementar múltiplas interfaces.

O diagrama UML a seguir ilustra o padrão Class Adapter:

Neste diagrama, a Adapterclasse herda da Adapteeclasse em vez de compô-la. E o Operation()método da Adapterclasse chama o SpecificOperation()método da Adapteeclasse.

Exemplo de adaptador de classe

O exemplo a seguir é igual ao exemplo que usa o padrão de adaptador de objeto, mas usa o padrão de adaptador de classe:

namespace ClassAdapter;

// The third-party PaymentProcessor class
public class PaymentProcessor
{
    public void ProcessPayment(decimal amount)
    {
        Console.WriteLine($"You have paid {amount:C}.");
    }
}

// Our application's IPaymentProvider interface
public interface IPaymentProvider
{
    void MakePayment(string details, decimal amount);
}

// The adapter class that adapts the PaymentProcessor to the IPaymentProvider interface
public class PaymentProviderAdapter : PaymentProcessor, IPaymentProvider
{
    public void MakePayment(string details, decimal amount)
    {
        Console.WriteLine($"Making a payment for: {details}");
        ProcessPayment(amount);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        var paymentProvider = new PaymentProviderAdapter();

        paymentProvider.MakePayment("C# design pattern course", 100.0m);
    }
}Linguagem de código:  C#  ( cs )

Resumo

  • O padrão Adapter permite que objetos com interfaces incompatíveis trabalhem juntos.
  • O padrão Object Adapter usa a composição enquanto a classe Class Adapter usa herança.

Deixe um comentário

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