Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Dúvida sobre o Pattern Observer.

No cenário da aula, é um cenário de emissão de note fiscal e que ao emitir uma nota, tb deve ser enviado um email, um sms e persistir esses dados.

Quais seriam os participantes nesse contexto? Suponho que o AcaoAposGerarNota seja um "Observer", EnviadorDeEmail, EnviadorDeSms e NotaFiscalDao, são "ConcreteObserver", e o NotaFiscalBuilder seja o "ConcreteSubject"? Não vi quem fez o papel do "Subject"...

As referências do papeis eu vi aqui no: https://www.dofactory.com/net/observer-design-pattern

E a aula refere-se ao curso: https://cursos.alura.com.br/course/design-patterns-dotnet/task/2627

Alguém poderia me ajudar? Outra dúvida, a implementação do pattern pode variar de uma pessoa para outra, exemplo nesse padrão podem ter várias formas de implementação?

1 resposta

Olá Jéssica, Tudo bem?

Usando o exemplo este padrão é util para permitir que você acione uma determinada ação quando for necessária, de forma que a classe que executa a ação não precisa ter uma implementação específica para cada pessoa que precisa ser notificada.

Normalmente este padrão segue o que foi apresentado na aula, o básico do padrão é ter:

  • Uma entidade que realiza a ação (muda de estado)
  • Entidades que assinam ou subscrevem a entidade que realiza a ação para serem notificadas (e tomarem ou não uma ação em cima disso).

Normalmente as entidades que assinam tem que aderir a um contrato, no exemplo da aula o contrato era a interface AcaoAposGerarNota, que determinava um método a ser chamado.

Em relação aos papeis:

  • NotaFiscalBuilder é o Subject e o Concrete Subject, uma vez que não usa uma interface, mas possui mecanismos para adicionar observers.
  • EnviadorDeEmail é um dos Concrete Observers
  • Impressora é um dos Concrete Observers
  • NotaFiscalDao é um dos Concrete Observers
  • EnviadorDeSms é um dos Concrete Observers
  • AcaoAposGerarNota é o Observer

No exemplo da aula a assinatura se dá por meio do método AdicionaAcao, neste caso suponhamos que no futuro você deseje logar todas as notas fiscais geradas em um arquivo de LOG com data e hora, você pode criar uma classe NFLogger

public class NFLogger : AcaoAposGerarNota 
{
    public void Executa(NotaFiscal notaFiscal) 
    {
        // Lógica para armazenar no sistema de Log
    // Seja arquivo, banco ou outra coisa.
    }
}

E você adiciona ele como observador usando o AdicionaAcao.

É importante notar que no exemplo não há um método para cancelar uma assinatura, mas em algumas implementações você pode ter um mecanismo para isso, suponhamos que você tenha uma aplicação desktop que tenha uma janela e um icone de bandeja.

Você pode adicionar ambos como observadores, tanto a janela quanto o icone da bandeja apresentam uma informação sobre o progresso, o icone que mostra o estado do programa com uma imagem ao lado do relógio, a aplicação mostra um texto na barra de estado, sobre a tarefa que ele está realizando por exemplo (envio de e-mails, processamento de números, etc), mas em algum momento você fecha a janela (ela deixa de existir), neste caso quando a aplicação mudar de estado e tentar notificar a janela ela pode encontrar uma referência nula.

Nestes casos você normalmente usa o Finalize ou Dispose se ele for uma interface do IDisposable para informar ao Subject que você não quer mais ser observador dele, e só o icone continuaria a observar, quando você abrisse uma nova janela esta poderia se registrar como observer da aplicação.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software