Observer01 / 13 · Capa
00:00 / 09:35
parado Resumo ↗
Engenharia de Software · Cap. 6 · Padrões de Projeto

Observer.

Como um objeto avisa vários outros que algo mudou, sem precisar saber quem eles são.
Nicolas Garcia
Ciência da Computação · 5º período
Padrão comportamental · GoF, 1994
Outubro de 2026
O problema

O pedido foi pago. Quem precisa saber?

Quatro coisas precisam acontecer: enviar o e-mail, baixar o estoque, emitir a nota fiscal e avisar a logística.

Saída A · chamada direta

O Pedido chama os quatro serviços

Cada novo interessado obriga a editar Pedido, que passa a depender de e-mail, estoque, fiscal e logística.

Saída B · polling

Cada serviço pergunta “já pagou?”

Gasta recurso enquanto nada acontece e atrasa a reação quando acontece.

O acoplamento está no lugar errado: quem muda não deveria conhecer quem reage.
Observer · Padrões de Projeto02 / 13
A ideia

Em vez de perguntar, você se inscreve.

Quando o estado muda, o aviso chega até quem se inscreveu.

“Definir uma dependência um-para-muitos entre objetos, de modo que, quando um objeto muda de estado, todos os seus dependentes são notificados e atualizados automaticamente.”
Intenção · Gamma, Helm, Johnson e Vlissides, 1994
Também conhecido comoPublish–SubscribeDependentsListener
Observer · Padrões de Projeto03 / 13
Estrutura

Quatro papéis, duas interfaces

  • SubjectGuarda a lista e oferece inscrever, cancelar e notificar.
  • ObserverInterface de retorno, com um método: atualizar().
  • Concrete­SubjectGuarda o estado real e dispara a notificação.
  • Concrete­ObserverImplementa a reação. Podem ser vários, independentes.
«INTERFACE» Subject + inscrever(o) + cancelar(o) + notificar() «INTERFACE» Observer + atualizar() observadores 0..* ConcreteSubject - estado + getEstado() + setEstado(e) ConcreteObserver - subject + atualizar() getEstado() notificar() → atualizar()
Observer · Padrões de Projeto04 / 13
O fluxo

Inscrever, mudar, notificar

Cliente Pedido · Subject EnviarEmail BaixarEstoque 1 inscrever(email) 2 inscrever(estoque) 3 setStatus(PAGO) · o estado muda 4 atualizar(this) 5 getStatus() · pull 6 atualizar(this) 7 getStatus()
O Pedido não sabe o que EnviarEmail e BaixarEstoque fazem. Só sabe que os dois implementam Observador.
Observer · Padrões de Projeto05 / 13
Implementação em Java

Cabe numa tela

Contrato + Subjectpublic interface Observador { void atualizar(Pedido p); } public class Pedido { private final List<Observador> obs = new ArrayList<>(); private Status status; public void inscrever(Observador o) { obs.add(o); } public void cancelar(Observador o) { obs.remove(o); } public void setStatus(Status novo) { this.status = novo; notificar(); // mudou → avisa } private void notificar() { for (Observador o : List.copyOf(obs)) o.atualizar(this); } public Status getStatus() { return status; } }
Observadores + usoclass EnviarEmail implements Observador { public void atualizar(Pedido p) { if (p.getStatus() == Status.PAGO) mailer.enviar("Pagamento confirmado"); } } class BaixarEstoque implements Observador { public void atualizar(Pedido p) { /* ... */ } } Pedido pedido = new Pedido(); pedido.inscrever(new EnviarEmail()); pedido.inscrever(new BaixarEstoque()); pedido.setStatus(Status.PAGO); // os dois reagem
Aberto/Fechado na prática · para emitir a nota fiscal, crie EmitirNota e chame inscrever. A classe Pedido não muda.
Observer · Padrões de Projeto06 / 13
Decisão de projeto

Quem carrega o dado: push ou pull?

Push · o Subject envia o dado
atualizar(status, valor)

Direto e explícito. Mas o Subject precisa adivinhar o que cada observador vai usar, e a assinatura cresce a cada caso novo.

Pull · o observador busca
atualizar(subject)

O aviso só diz “eu mudei” e cada observador lê o que interessa. É mais flexível e custa uma chamada a mais. É o que o código anterior usa.

Na prática · híbrido
Um objeto de evento com o essencial, mais a referência ao Subject: atualizar(PedidoPagoEvent e).
Observer · Padrões de Projeto07 / 13
No mundo real

Você já usa isso todo dia

OndeComo aparece
addEventListenerO DOM é um Observer. Um clique é uma notificação.
React · VueO componente observa o estado e renderiza de novo.
store.subscribeRedux, Vuex e Pinia: a interface observa a store.
@EventListenerSpring publica eventos da aplicação.
OndeComo aparece
ObservableRxJS: Observer com fluxo e operadores.
post_saveDjango signals avisam os receptores conectados.
WebhooksObserver pela rede: a loja chama o seu servidor.
Kafka · RabbitMQPub/Sub distribuído, a mesma ideia com um broker.
OrigemNo MVC do Smalltalk-80, a View observa o Model.
Observer · Padrões de Projeto08 / 13
Benefícios

O que o padrão entrega

Baixo acoplamento

O Subject conhece só a interface Observer, nunca as classes concretas.

Aberto/Fechado

Novos observadores entram sem editar uma linha do Subject.

Vínculo dinâmico

Inscrição e cancelamento em tempo de execução, não de compilação.

Broadcast

Um evento, N reações. O emissor não sabe nem quantas são.

Observer · Padrões de Projeto09 / 13
Custos

E o preço que ele cobra

Vazamento de memória

O lapsed listener: ninguém chamou cancelar() e o Subject mantém o observador vivo para sempre.

Ordem indefinida

O padrão não garante a sequência das notificações. Código que depende dela está errado.

Depuração difícil

O fluxo sai da pilha de chamadas: você vê o estado mudar e não vê quem reagiu.

Falha em cadeia

Na versão síncrona, um observador lento trava os seguintes e uma exceção interrompe o laço.

Observer · Padrões de Projeto10 / 13
Comparação

Observer × Publish/Subscribe

Observer · GoFPub/Sub · mensageria
ConhecimentoO Subject mantém a lista de observadores.Ninguém se conhece: há um broker no meio.
AcoplamentoBaixo, com referência direta em memória.Quase nulo, só o nome do tópico.
EscopoDentro de um processo.Entre serviços, máquinas e redes.
ExecuçãoNormalmente síncrona.Assíncrona, com fila e reentrega.
ExemplosaddEventListener, Spring EventsKafka, RabbitMQ, webhooks, SNS
Mesma intenção, escalas diferentes. Pub/Sub é o Observer com um intermediário.
Observer · Padrões de Projeto11 / 13
Critério

Quando usar, e quando evitar

Use quando
  • A mudança exige reações que você não conhece de antemão.
  • O conjunto de interessados varia em tempo de execução.
  • Você quer separar o que aconteceu do que fazer a respeito.
Evite quando
  • Há um único dependente fixo. A chamada direta é mais clara.
  • Ordem ou garantia de entrega são requisitos de negócio.
  • As reações precisam ser transacionais com a mudança.
Observer · Padrões de Projeto12 / 13
Para levar
  1. 01O Observer troca “eu te chamo” por “me avise”.
  2. 02Quem emite o evento conhece só a interface, não quem reage.
  3. 03O preço é a rastreabilidade: ganha flexibilidade, perde o fluxo explícito.
Obrigado.Perguntas?
Gamma et al., Design Patterns, 1994 · Freeman e Robson, Head First Design Patterns, 2020 · Valente, Engenharia de Software Moderna, cap. 6 · refactoring.guru
01 · Capa · 20 s

“Bom dia. Meu tema é o padrão Observer, um dos padrões comportamentais do catálogo da Gangue dos Quatro.”

Não leia o subtítulo. Vá direto ao problema; a definição vem depois.

“Imagina um e-commerce. O pedido foi pago. A partir daí quatro coisas precisam acontecer: mandar e-mail, baixar estoque, emitir nota e avisar a logística.”

“A solução ingênua é a classe Pedido chamar os quatro serviços. Funciona até chegar o quinto. Aí você abre Pedido de novo, e ela agora conhece e-mail, estoque, fiscal e logística.”

“A outra saída seria cada serviço ficar perguntando ‘já pagou?’. É polling: desperdício e atraso.”

Feche com a caixa verde, devagar: o acoplamento está no lugar errado.

“A ideia do Observer é inverter isso: em vez de perguntar, você se inscreve. Quando o estado muda, o aviso vem até você.”

“A definição formal do GoF é essa: dependência um-para-muitos. Um objeto muda, todos os dependentes são notificados automaticamente.”

Leia só os trechos em negrito da citação. Cite os outros nomes em uma frase.

“Estruturalmente são quatro papéis e duas interfaces.”

“O Subject é quem tem algo a anunciar: guarda a lista e expõe inscrever, cancelar e notificar. O Observer é a interface de quem quer ser avisado, normalmente com um método só.”

“Embaixo, as implementações concretas. A seta verde é o coração do padrão: notificar() chama atualizar() em cada observador. A tracejada de volta é o observador lendo o estado.”

Aponte o losango no topo: é a agregação que garante que o Subject só conhece o tipo Observer.

“Em sequência fica ainda mais claro. Passos 1 e 2: o cliente inscreve dois observadores no pedido.”

“Passo 3, o estado muda: setStatus(PAGO). Esse é o gatilho.”

“Passos 4 a 7: o pedido percorre a lista e chama atualizar() em cada um. Cada observador lê o que precisa e faz o seu trabalho.”

Frase-chave: “o Pedido não sabe o que esses dois fazem, só sabe que os dois implementam a interface.”

“Em código cabe numa tela. À esquerda, a interface com um método e o Subject: uma lista, inscrever, cancelar e o setStatus que chama notificar() logo depois de mudar o estado.”

“À direita, dois observadores concretos que não se conhecem. E o uso: instancia, inscreve os dois, muda o status, e os dois reagem.”

“O ponto principal está embaixo: para acrescentar a nota fiscal, eu crio uma classe e chamo inscrever. A classe Pedido não muda. Isso é o Princípio Aberto/Fechado.”

Se o tempo apertar, vá direto à caixa verde. Cite o List.copyOf só se perguntarem.

“Tem uma decisão de projeto aqui: quem carrega o dado.”

“No push, o Subject manda os valores no próprio aviso. É direto, mas ele precisa adivinhar do que cada observador precisa, e a assinatura do método incha.”

“No pull, o aviso é só ‘eu mudei’ e cada um busca o que interessa. É o que está no código do slide anterior.”

Feche: na prática se usa híbrido, um objeto de evento com o essencial.

“E isso não é só teoria. Todo mundo aqui já escreveu um Observer sem saber.”

“addEventListener é literalmente isso: o botão é o subject, a sua função é o observer. React e Vue: o componente observa o estado. Spring tem @EventListener, Django tem signals, e webhook é Observer pela rede: a loja avisa o seu servidor que houve uma venda.”

Não leia os oito. Escolha três que a turma conheça e diga que o resto está no slide.

“Resumindo os ganhos: baixo acoplamento, porque o Subject só conhece a interface. Aberto/Fechado, porque dá para estender sem editar. Vínculo dinâmico, porque a lista muda em execução. E broadcast de graça.”

Ritmo rápido. É um slide de confirmação.

“Mas todo padrão cobra um preço.”

“O clássico é o lapsed listener: você esqueceu de cancelar a inscrição, o Subject continua segurando a referência e o objeto nunca é coletado. Vazamento de memória.”

“Segundo: a ordem não é garantida. Se o estoque precisa baixar antes de o e-mail sair, o Observer sozinho não resolve.”

“E o que mais dói no dia a dia: depuração. Você vê o estado mudar e não vê quem reagiu.”

Dê tempo a esse slide. É aqui que você mostra profundidade.

“Uma confusão comum: Observer e Publish/Subscribe são a mesma coisa?”

“Mesma intenção, escalas diferentes. No Observer o Subject tem a lista, existe referência direta. No Pub/Sub há um broker no meio: quem publica nem sabe se existem assinantes, e a entrega é assíncrona, entre máquinas.”

Fecho: “Pub/Sub é o Observer com um intermediário.”

“O critério prático. Use quando uma mudança exige reações que você não conhece de antemão, quando o número de interessados varia em execução e quando quer separar o que aconteceu do que fazer a respeito.”

“Evite quando só há um dependente fixo, porque aí a chamada direta é mais clara. E evite quando ordem, entrega garantida ou transação forem requisitos: isso é trabalho de fila.”

“Fechando com três frases: o Observer troca ‘eu te chamo’ por ‘me avise’. Quem emite não precisa conhecer quem reage. E o preço é a rastreabilidade.”

“Obrigado. Alguma pergunta?”

As perguntas prováveis, com resposta, estão no Resumo (botão no topo).