Adapter Pattern - Design Patterns com Typescript

Adapter Pattern - Design Patterns com Typescript

Nesse artigo pretendo apresentar de uma forma simplificada o conceito de Adapter Pattern, que é um padrão de projeto extremamente útil no dia a dia para qualquer desenvolvedor. Sua função é converter uma interface de uma classe para outra esperada pelo cliente, possibilitando que classes com interfaces incompatíveis trabalhem juntas.

Para simplificar o conceito, imagine que tenha um novo notebook que comprou fora do brasil, seu plugue de energia vem no padrão europeu, infelizmente incompatível com as tomadas brasileiras, para resolver esse problema é simples, vai precisar de um adaptador.

Bom, o Adapter Pattern tem exatamente a mesma função, conectar dois pontos incompatíveis entre si.

Com o conceito entendido, hora de colocar isso no código em um exemplo mais real encontrado no dia a dia de muitos desenvolvedores, de forma muito simplificada é claro, mas que já vai nos dar uma boa ideia de como expandirmos e aplicarmos isso no nosso dia a dia.

Considere que tem hoje um sistema de log que salva em um arquivo local todas as informações geradas pela aplicação, e que esse possui a seguinte interface e implementação:

1
2
3
4
5
6
7
8
9
10
interface Logger {
info(message: string): Promise<void>;
}

class FileLogger implements Logger {
public async info(message: string): Promise<void> {
console.info(message);
console.info('This Message was saved with FileLogger');
}
}

Essa mesma implementação é usada por todo o sistema e sempre gerado um log o mesmo é tratado por essa classe FileLogger como no exemplo abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class NotificationService {
protected logger: Logger;

constructor (logger: Logger) {
this.logger = logger;
}

public async send(message: string): Promise<void> {
//... Implementation
await this.logger.info(`Notification sended: ${message}`);
}
}

// Inicialização com o FileLogger
(async () => {
const fileLogger = new FileLogger();
const notificationService = new NotificationService(fileLogger);
await notificationService.send('My notification');
})();

Ao rodar esse código é esperado algo como:

1
2
3
# tsc && node adapter/index.js
Notification sended: Foii
This Message was saved with FileLogger

Porém agora precisamos usar uma nova forma de salvar os logs, pois com o crescimento de nossa aplicação, salvar em disco não é mais uma alternativa, assim precisamos usar uma implementação que responde pela seguinte interface e implementação:

1
2
3
4
5
6
7
8
9
10
interface CloudLogger {
sendToServer(message: string, type: string): Promise<void>;
}

class AwsLogger implements CloudLogger {
public async sendToServer(message: string, type: string): Promise<void> {
console.info(message);
console.info('This Message was saved with AwsLogger');
}
}

Ou seja, para que possamos usar essa nova classe precisaríamos refatorar todo nosso código para usar o novo formato de envio de log, ou usar um adapter, o que convenhamos, parece uma opção bem melhor 🙂.
Esse adapter poderia ser algo como:

1
2
3
4
5
6
7
8
9
10
11
class CloudLoggerAdapter implements Logger {
protected cloudLogger: CloudLogger;

constructor (cloudLogger: CloudLogger) {
this.cloudLogger = cloudLogger;
}

public async info(message: string): Promise<void> {
await this.cloudLogger.sendToServer(message, 'info');
}
}

Com esse adapter poderíamos enviar uma instância do mesmo e manter todo o código de nossas implementações intacto, apenas alterando a inicialização como pode ser visto no exemplo abaixo:

1
2
3
4
5
6
7
// Inicialização com o AwsLogger
(async () => {
const awsLogger = new AwsLogger();
const cloudLoggerAdapter = new CloudLoggerAdapter(awsLogger);
const notificationService = new NotificationService(cloudLoggerAdapter);
await notificationService.send('My notification');
})();

Assim teríamos uma saída esperada:

1
2
3
# tsc && node adapter/index.js
Notification sended: Foii
This Message was saved with AwsLogger

Como podem perceber esse é um padrão extremamente útil e é fundamental para qualquer desenvolvedor o entendimento desse padrão.

Bom por hoje é isso, mais em breve pretendo escrever outros artigos como esse, com intuito de simplificar e trazer para o nosso dia a dia os padrões de projetos ou design patterns mais comuns aplicados usando o typescript.

O Código completo para esse implementação pode ser encontrado em: https://github.com/meneguite/typescript-design-patterns/blob/master/adapter/index.ts

Outros padrões de Projetos:

Comentários

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×