Adapter Pattern no C#

De acordo com o Wikipédia, o Adapter Pattern é um padrão de projeto de software que permite que a interface de uma classe existente seja usada como outra interface. Geralmente é utilizado para fazer as classes existentes funcionarem com outras que não compartilham dos mesmos requisitos, sem modificar seu código-fonte.

Nem sempre é prático reescrever grandes pedaços do seu sistema para interagir corretamente com novas bibliotecas de terceiros ou sistemas externos. É nesses casos que este padrão de desenvolvimento é muito útil.

Intenção

– O adaptador permite que as classes trabalhem juntas que de outra forma não poderiam por causa de interfaces incompatíveis.
– Encapsula uma classe existente com uma nova interface.
– A combinação de um componente antigo com um novo sistema.

Implementação

Vamos imaginar nesse exemplo que existe uma máquina em uma linha de produção. Esta máquina possui seu código fonte para executar determinadas ações. A classe que lida com essas ações é mostrada abaixo com o nome de LineFactoryMachine.

using System;

namespace AdapterPattern
{
    public class LineFactoryMachine
    {
        public void ExecuteAction(int actionNumber)
        {
            Console.WriteLine("Executing action " + actionNumber);
        }
        public void RebootMachineServiceOptions(string key)
        {
            Console.WriteLine("Reboot Machine Service Options action: " + key);
        }
    }
}

Imagine então que vamos usar um novo sistema automático para executar as ações. Porém esse novo sistema possui sua própria implementação que não é compatível com o programa atual.

Devemos então, primeiramente, criar uma interface que disponibilizará os métodos necessários para o cliente (novo sistema).

namespace AdapterPattern
{
    public interface IMachine
    {
        void Execute(object action);
        void Reboot(object action);
    }
}

Agora que já temos a interface, podemos criar a classe adaptadora. Ela vai ser responsável pela implementação necessária e a realização das chamadas ao sistema legado.

using System;

namespace AdapterPattern
{
    public class MachineComputerAdapter : IMachine
    {

        LineFactoryMachine oldMachine;

        public MachineComputerAdapter(LineFactoryMachine newMachine)
        {
            oldMachine = newMachine;
        }

        public void Execute(object action)
        {
            Console.WriteLine("Execute from Machine Computer Adapter");
            int result;
            if (int.TryParse(action.ToString(), out result))
            {
                oldMachine.ExecuteAction(result);
                return;
            }
            throw new FormatException();
        }

        public void Reboot(object action)
        {
            Console.WriteLine("Reboot from Machine Computer Adapter");
            if (!string.IsNullOrEmpty(action.ToString()))
            {
                oldMachine.RebootMachineServiceOptions(action.ToString());
                return;
            }
            throw new FormatException();
        }
    }
}

O adaptador recebe em seu construtor uma instância de LineFactoryMachine, esta instância vai ser usada para a realização das chamadas ao sistema legado dentro dos métodos implementados da interface.

Assim que toda a implementação estiver pronta, podemos então realizar nossa chamada, criando uma instância da LineFactoryMachine, e enviando ela para o construtor do MachineComputerAdapter, que vai executar as chamadas para o cliente.

using System;

namespace AdapterPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Adapter Pattern!");

            var lineFacMachine = new LineFactoryMachine();
            IMachine machine = new MachineComputerAdapter(lineFacMachine);

            machine.Execute(12);
            machine.Reboot("RebootAll");
        }
    }
}

Resultado da execução

Adapter Pattern!
Execute from Machine Computer Adapter
Executing action 12
Reboot from Machine Computer Adapter
Reboot Machine Service Options action: RebootAll

Conclusão

É importante lembrar que um adaptador é destinado a envolver o adaptee (neste caso o LineFactoryMachine) e expor uma interface de destino para o cliente. O funcionamento é como de uma tradução, ele vai traduzir a solicitação do cliente para o sistema de destino.

Uma grande vantagem desse é que só porque uma interface não está em conformidade com o que seu sistema está esperando, não significa que seu sistema precisa mudar. Este padrão de design é uma técnica que ajuda a preencher a lacuna entre duas interfaces incompatíveis. Isso permitirá que você continue usando seus sistemas existentes e integre fontes externas neles sem necessidade de alterações no seu código legado.

Qualquer dúvida ou dicas, entre em contato: leandrolt@gmail.com

Principais referências

– https://en.wikipedia.org/wiki/Adapter_pattern
– https://refactoring.guru/design-patterns/adapter
– https://www.geeksforgeeks.org/adapter-pattern/
– https://sourcemaking.com/design_patterns/adapter
– https://www.devmedia.com.br/design-patterns-adapter/17160
– https://www.tutorialspoint.com/design_pattern/adapter_pattern.htm
– https://www.dofactory.com/net/adapter-design-pattern

Leave a Reply

Your email address will not be published. Required fields are marked *