Um padrão de projeto é um modelo que resolve um problema comumente recorrente no projeto de software.
O padrão observador, também conhecido como padrão publicar-assinar, é um padrão comportamental. Ele permite que você notifique vários objetos ou assinantes sobre qualquer evento publicado no objeto que eles estão observando.
Aqui você aprenderá como implementar o padrão de design do observador no TypeScript.
O Padrão do Observador
O padrão observador funciona definindo um relacionamento um-para-muitos entre o publicador e seus assinantes. Quando um evento ocorrer no editor, ele notificará todos os assinantes desse evento. Um exemplo generalizado desse padrão é Ouvintes de evento JavaScript.
Para contextualizar, suponha que você esteja criando um rastreador de estoque que rastreia o número de produtos em sua loja. Nesse caso, sua loja é o assunto/editor e seu inventário é o observador/assinante. Usar o padrão de projeto do observador seria ideal nessa situação.
No padrão de projeto do observador, sua classe de assunto deve implementar três métodos:
- Um anexar método. Este método adiciona um observador ao assunto.
- A separar método. Este método remove um observador de um assunto.
- A notificar/atualizar método. Este método notifica os observadores do sujeito quando o estado muda no sujeito.
Sua classe de observador deve implementar um método, o atualizar método. Este método reage quando há uma mudança no estado de seu sujeito.
Implementando as classes Subject e Observer
O primeiro passo para implementar esse padrão é criar interfaces para as classes subject e observer, para garantir que implementem os métodos corretos:
// Interface Assunto/Editor
interfaceAssunto{
attachObserver (observador: Observer): vazio;
detachObserver (observador: Observer): vazio;
notifyObservador(): vazio;
}
// Interface Observador/Assinante
interfaceObservador{
atualizar(assunto: Assunto): vazio;
}
As interfaces no bloco de código acima definem os métodos que suas classes concretas devem implementar.
Uma classe de assunto concreto
O próximo passo é implementar uma classe de assunto concreta que implemente o Assunto interface:
// Assunto
aulaLojaimplementosAssunto{}
Em seguida, inicialize o Assuntoestado de Loja aula. Os observadores do sujeito reagirão às mudanças nesse estado.
Nesse caso, o estado é um número e os observadores reagirão a um aumento no número:
// estado do assunto
privado númeroDeProdutos: número;
Em seguida, inicialize uma matriz de observadores. Esta matriz é como você acompanhará os observadores:
// inicializando observadores
privado observadores: Observador[] = [];
Você pode encontrar algumas implementações do padrão observador usando a Definir estrutura de dados no lugar de uma matriz para acompanhar o observador. O uso de um conjunto garantirá que o mesmo observador não apareça duas vezes. Se você quiser usar uma matriz, verifique se há observadores duplicados em seu anexar método.
Em seguida, você deve implementar o Assuntoos métodos—anexar, separar, e notificar/atualizar- em sua classe concreta.
Para implementar o anexar método, primeiro verifique se o observador já está anexado e emita um erro se estiver. Caso contrário, adicione o observador ao array usando o comando método de matriz JavaScript, empurrar:
// Anexando Observador(es)
attachObserver (observador: Observer): vazio {
// Verifica se o observador já foi anexado
const observadorExiste = esse.observers.includes (observador);if (observadorExiste) {
lançarnovoErro('Observer já foi inscrito ');
}
// Adiciona um novo observador
esse.observadores.empurrar(observador);
}
Em seguida, implemente seu separar método encontrando o índice e removendo-o da matriz usando o JavaScript emendar método.
Pode haver cenários em que o observador que você está tentando desanexar já foi desanexado ou não foi inscrito em primeiro lugar. Você deve lidar com esses cenários adicionando uma instrução condicional para verificar se o observador está na matriz ou no conjunto, conforme o caso.
// Desvinculando o(s) Observador(es)
detachObserver (observador: Observer): vazio {
console.registro(`Retirando o observador ${JSON.stringify (observador)}`);
const observadorIndex = esse.observers.indexOf (observador);if (observerIndex -1) {
lançarnovoErro('Observador não existe');
}
esse.observadores.juntar(observerIndex, 1);
console.log('Observador destacado...');
}
Em seguida, implemente seu notificar/atualizar fazendo um loop em sua lista de observadores e chamando o método atualizar método de cada um:
// Notificando Observadores
notifyObservador(): vazio {
console.log('Notificando observadores...');
para (const observador deesse.observadores) {
observador.atualizar(esse);
}
}
Finalmente, para o Assunto class, implemente um método que manipule o estado e então notifique os observadores sobre a mudança chamando seus notificar/atualizar método. Este exemplo é uma simplificação de como um sujeito pode executar uma ação e então informar os observadores:
// Alterando o estado e notificando os observadores
novoProduto (produtos: número): vazio {
esse.numberOfProducts += produtos;
console.log('Novo produto adicionado à loja');
esse.notifyObserver();
}
Classes de Observadores Concretos
Crie uma classe ou classes de observadores para se inscrever no editor. Cada classe de observador deve implementar o Observador interface.
As classes observadoras implementarão um notificar/atualizar método que somente o sujeito que eles estão observando deve chamar. Este método deve conter toda a lógica de negócios que você precisa para executar em resposta a uma mudança no estado do assunto:
// Observador Concreto 1
aulaInventárioimplementosObservador{
atualizar(): vazio {
console.log('Novo produto adicionado à loja, atualização de estoque...');
// A lógica de negócios real vai aqui...
}
}
// Observador Concreto 2
aulaClienteimplementosObservador{
atualizar(): vazio {
console.log('Novo produto adicionado à loja, tenho que ir conferir...');
// A lógica de negócios real vai aqui...
}
}
Usando o padrão Observer
Para usar esse padrão, instancie as classes subject e observer concretas. Depois de fazer isso, ligue para o Assunto anexar método e passe a instância do Observer como um argumento. Em resposta, o sujeito adicionará essa instância à sua lista de observadores:
// Instanciando Subject e Observer
const loja = novo Loja();
const inventário = novo Inventário();
const cliente = novo Cliente()
// Inscrevendo objetos no editor
loja.attachObserver(inventário);
loja.attachObserver(cliente);
// Mudando o estado do assunto
loja.novo produto(30);
Este código simula uma mudança de estado. A alteração acionará o método de notificação no Assunto aula. Este método, por sua vez, chama o notificar método em cada um de seus observadores. Cada observador executará sua própria lógica de negócios.
Você só deve usar esse padrão quando as alterações no estado de um objeto afetam outros objetos e o conjunto de objetos envolvidos é desconhecido ou dinâmico.
Vantagens de usar o padrão Observer
Usar esse padrão em seu código permite que você mantenha o princípio abrir/fechar. Você pode adicionar quantos assinantes quiser e estabelecer relacionamentos entre objetos em tempo de execução, sem alterar o código do assunto.