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.
Subscribe to my newsletter
Read articles from André Martins directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
