Handler Map

Imagine que você está em um cenário onde tem várias funções que precisam ser executadas conforme um caminho seja passado por parâmetro, por exemplo: dentro de um domínio de clientes, precisamos executar funções a partir de uma chamada desse path, e, nesse caso, temos sabedoria para não resolver isso com switch case ou da forma abaixo.
class Cliente {
public constructor(private _id: number, private _name: string) {}
get clientes(): number {
return this._id;
}
// outros comportamentos do cliente
}
class ClienteService {
public execute(path: string) {
if (path === "sincronizarImagens") {
// lógica para sincronizar as imagens do cliente
}
if (path === "sincronizarReport") {
// lógica para sincronizar os relatórios do cliente
}
if (path === "sincronizarLogs") {
// lógica para sincronizar os logs do cliente
}
}
}
Iniciando solução
Podemos pensar em excluir essa lógica de ifs, e uma forma de fazer isso é com o Handler Map.
A primeira parte é definir um tipo onde teremos uma chave e o tipo de parâmetros da função de callback. Perceba que, nesse ponto, podemos usar qualquer string como tipo da chave, e nos parâmetros estamos esperando o ID e não vamos retornar nada.
type HandlerMap = {
[key: string]: (id: number) => void;
};
Agora precisamos de uma função para resolver nossa callback conforme o parâmetro que passarmos, mas o detalhe é que não vamos passar parâmetro nenhum, te mostro já.
class ClientService {
private resolverHandlerMapByName(): HandlerMap {
return {
sincronizarImagens:(id: number) => this.searchImages(id),
sincronizarReport(id: number) => this.sincronizarReport(id),
sincronizarLogs(id: number) => this.sincronizarLogs(id),
}
}
sincronizarImagens(id: number): void {
// lógica para sincronizar as imagens do cliente
}
sincronizarReport(id: number): void {
// lógica para sincronizar os relatórios do cliente
}
sincronizarLogs(id: number): void {
// lógica para sincronizar os logs do cliente
}
}
Conforme o exemplo acima, resolvemos nossa execução de forma transparente, sem a necessidade de verificações estranhas.
Como usar?
class ClientService {
execute(path: string) {
const id = 123;
const handler = this.resolverHandlerMapByName()[path]
handler(id);
}
private resolverHandlerMapByName(): HandlerMap {
return {
sincronizarImagens:(id: number) => this.searchImages(id),
sincronizarReport(id: number) => this.sincronizarReport(id),
sincronizarLogs(id: number) => this.sincronizarLogs(id),
}
}
sincronizarImagens(id: number): void {
// lógica para sincronizar as imagens do cliente
}
sincronizarReport(id: number): void {
// lógica para sincronizar os relatórios do cliente
}
sincronizarLogs(id: number): void {
// lógica para sincronizar os logs do cliente
}
}
Dessa forma conseguimos resolver nossa chamada com HandlerMap de forma transparente, há outras formas de resolver isso também, mas essa é uma forma que deixa as coisas bem legíveis.

![Iniciando leitura de logs do MySQL com Debezium [Parte-1]](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fstock%2Funsplash%2FLCesurcI3PM%2Fupload%2F1502726d43b386a91abc8aec9e513038.jpeg&w=3840&q=75)

