Resolvendo problemas de integração entre interfaces com padrões de projeto
Tags: patterns, designpatterns
Published: 2022-07-18 15:02:32

## Contéudo
[Introdução](#introducao)
[Decorator](#decorator)
[Adapter](#adapter)
[Facade](#facade)


### Introdução <a name="introducao"></a>
Sabemos ao lidar com sistemas do mundo real que um problema bastante frequente é a necessidade de integração com sistemas de terceiros. Sejam APIs para integração de um ERP, um CRM ou um sistema auxiliar para uma necessidade que os seus clientes tem.
Com isso, nos vemos com o dilema de como fazer para integrar nossos sistemas para se comunicar com esses outros sistemas. Não há tempo, nem mesmo disposição para sempre fazer uma refatoração do sistema para se comunicar a um parceiro.
Nesse artigo trago 3 padrões de projeto que podem ser um guia para essa necessidade.

Comparativo
Decorator: Acrescenta responsabilidades a uma interface
Adapter: Converte uma interface para outra
Facade: Simplifica uma interface

### Decorator <a name="decorator"></a>
O Decorator é um padrão de projeto estrutural que permite que você acople novos comportamentos para objetos ao colocá-los dentro de invólucros de objetos que contém os comportamentos.
Comportamento típicos que podem utilizar esse padrão são:
- Log;
- Cache;
A estrutura normal do Decorator é atuar como um wrapper para o objeto desejado. 
Exemplo de implementação:
```
IWeatherService innerService = new WeatherService(apiKey);
            IWeatherService withLoggingDecorator = new WeatherServiceLoggingDecorator(innerService, _loggerFactory.CreateLogger<WeatherServiceLoggingDecorator>());
            IWeatherService withCachingDecorator = new WeatherServiceCachingDecorator(withLoggingDecorator, _memoryCache);
            _weatherService = withCachingDecorator;
```
Nesse código é possível ver que o service _innerService_ é envolvido pelo Decorator **_WeatherServiceLoggingDecorator_** gerando o service _withLoggingDecorator_ que por sua vez é envolvido pelo Decorator **_WeatherServiceCachingDecorator_** gerando o service _withCachingDecorator_ que é o service final.
Uma analogia bastante utilizada é comparar essa implementação com uma cebola e suas camadas.

### Adapter <a name="adapter"></a>
O Adapter é um padrão de projeto estrutural e sua motivação é fazer com que uma interface de uma classe seja convertida para outra interface de acordo com o que o cliente espera.
Existem dois tipos de Adapters que podem ser implementados:
- Object adapter - utiliza composição, onde é realizada uma implementação de uma interface
- Class adapter - utiliza herança, onde é realizada uma herança da classe externa

A aplicabilidade desse padrão de projeto é ser usado quando a interface de uma biblioteca de terceiros ou algo similar não é compatível com o código atual da aplicação. Também pode ser aplicada para casos de chamadas a APIs, onde é necessária ou desejada a separação da parte do código responsável pela conversão dos dados recebidos da parte em que está a lógica de negócio do sistema. Esse padão é útil quando deseja-se utilizar várias implementações onde a estrutura é similar, mas existem diversas fontes externas (como diferentes APIs). Desse modo, todo o trabalho fica como responsabilidade da classe Adapter, separando essa camada do resto do sistema.

### Facade<a name="facade"></a>
O Facade é um padrão de projeto estrutural que fornece uma interface simplificada para uma biblioteca, um framework, ou qualquer conjunto complexo de classes.
Exemplos de usos:
* Classe muito complexa, onde são necessários apenas alguns dos métodos dela ou que seja apresentado algo mais intuitivo para uso do outro objeto. Uma classe facade faria essa intermediação fornecendo apenas alguns métodos para simplificar a implementação do objeto cliente
* Várias classes com métodos necessários para o objeto cliente. Uma classe facade faria a intermediação para simplificar em apenas 1 método a ser chamado.