Executando verificação de segurança...
21

O que são Observers

O Observer é um Design Pattern de comportamento que te cria um mecanismo de "notificação" para diversos objetos sobre qualquer evento que aconteça no objeto observado.

Se você já usou Angular ou RxJS, já viu os Observables da lib do ngrx que são basicamente uma implementação de um Observer.

Com o Observer, você cria uma estrutura onde se pode adicionar observadores que vão ser notificados à cada atualização que nem no fluxo abaixo.

Fluxo Observer

Exemplo prático

Vamos imaginar o seguinte cenário:

Em um jogo, o jogador pode receber dano, e, ao ocorrer esse evento, diferentes sistemas precisam ser notificados, como a barra de vida, um sistema de áudio para tocar sons de dor, e um sistema de log para registrar o evento.

Exemplo de Código

Imagine que estamos desenvolvendo esse sistema em JavaScript, onde o Jogador é o Observable e cada componente que precisa ser notificado (barra de vida, áudio, log de eventos) é um Observador.

  1. Observable (Jogador)
class Jogador {
  constructor() {
    this.observadores = [];
    this.vida = 100; // vida inicial do jogador
  }

  // Adicionar um observador
  adicionarObservador(observador) {
    this.observadores.push(observador);
  }

  // Remover um observador
  removerObservador(observador) {
    this.observadores = this.observadores.filter(obs => obs !== observador);
  }

  // Notificar todos os observadores
  notificar() {
    this.observadores.forEach(observador => observador.atualizar(this.vida));
  }

  // Reduzir a vida e notificar observadores se o jogador sofre dano
  receberDano(dano) {
    this.vida -= dano;
    console.log(`😨 Jogador recebeu ${dano} de dano. Vida atual: ${this.vida}`);
    this.notificar();
  }
}
  1. Observadores

Cada observador representa uma reação específica ao evento de dano e implementa o método atualizar.

Observador da Barra de Vida:

class BarraDeVida {
  atualizar(vida) {
    console.log(`📉 Atualizando barra de vida: ${vida} de vida restante.`);
  }
}

Observador de Áudio:

class SistemaDeAudio {
  atualizar(vida) {
    console.log(`🔊 Tocando som de dano. Vida atual do jogador: ${vida}`);
  }
}

Observador de Log de Eventos:

class LogDeEventos {
  atualizar(vida) {
    console.log(`📜 Registrando no log: jogador sofreu dano. Vida restante: ${vida}`);
  }
}
  1. Uso do Sistema

Agora, vamos criar o Jogador e adicionar observadores para simular as notificações.

// Instanciar o jogador
const jogador = new Jogador();

// Criar observadores
const barraDeVida = new BarraDeVida();
const sistemaDeAudio = new SistemaDeAudio();
const logDeEventos = new LogDeEventos();

// Adicionar observadores ao jogador
jogador.adicionarObservador(barraDeVida);
jogador.adicionarObservador(sistemaDeAudio);
jogador.adicionarObservador(logDeEventos);

// Simular o jogador recebendo dano
jogador.receberDano(20); // Reduz a vida e notifica observadores
jogador.receberDano(30); // Reduz ainda mais e notifica novamente

A saída será:

😨 Jogador recebeu 20 de dano. Vida atual: 80
📉 Atualizando barra de vida: 80 de vida restante.
🔊 Tocando som de dano. Vida atual do jogador: 80
📜 Registrando no log: jogador sofreu dano. Vida restante: 80

😨 Jogador recebeu 30 de dano. Vida atual: 50
📉 Atualizando barra de vida: 50 de vida restante.
🔊 Tocando som de dano. Vida atual do jogador: 50
📜 Registrando no log: jogador sofreu dano. Vida restante: 50

Neste exemplo, o padrão Observer permite que diferentes partes do sistema de jogo reajam automaticamente ao evento de dano, mantendo o código organizado e facilitando a adição de novos comportamentos.

Conclusão

Para encerrar, o padrão Observer é uma ótima escolha quando você precisa de um sistema que se adapte e responda a eventos em tempo real, permitindo que diferentes componentes reajam a mudanças sem que o código do sujeito principal precise ser alterado.

Em cenários de jogos, aplicativos de monitoramento e até em redes sociais, o Observer ajuda a criar arquiteturas flexíveis e modulares, facilitando tanto a manutenção quanto a expansão do sistema.

Esse padrão é amplamente aplicável, seja em interfaces reativas, notificações de eventos ou outros tipos de resposta a mudanças. Ele permite adicionar e remover observadores com facilidade, garantindo que o sistema se mantenha desacoplado e escalável.

Carregando publicação patrocinada...
4

racoelho, este nome observer faz me lembrar da época em que o Filipe Deschamps criou uma série de vídeos implementando o jogo da cobrinha multiplayer. Clicando na imagem a seguir, você confere um dos diversos vídeos da playlist em que o Filipe aplica o conceito de observers na prática.

IMAGE ALT TEXT

De onde surgiu a miniatura acima?

A miniatura do vídeo é "puxada" da sequência de imagens (0 a n) definidas automaticamente ou manualmente para a mídia no Youtube. O seguinte código markdown aproveita então a primeira imagem miniatura 0.jpg.

[![IMG ALT TEXT](http://img.youtube.com/vi/4OLCrClb_So/0.jpg)](https://youtu.be/4OLCrClb_So "VidTitle")

As ocorrências do id (aqui 4OLCrClb_So) podem ser substituídas pelo id correspondente ao vídeo que desejar indicar na forma de miniatura clicável. No exemplo acima, as ocorrências referem-se ao caminho da imagem e ao weblink para o vídeo, respectivamente.

IMG ALT TEXT é uma breve descrição de texto para a imagem. Esse bloco é capturado por leitores de tela (ou outra tecnologia assistiva) fornecendo ao leitor informações sobre a finalidade da imagem. O texto alternativo não deve apenas descrever o que a imagem contém, mas também fornecer contexto sobre como a imagem se relaciona com o conteúdo da página harvard.edu

VidTitle é um texto que aparecerá ao pairar o ponteiro do mouse sobre a imagem.

PS: Não sou um guru do markdown mas aprendendo com vários experts aqui no Tabnews.

2

O Observer é um dos padrões clássicos do GoF, criado para programação orientada a objetos. Ironia do destino, ele se tornou a base da web!

Os event listeners do JavaScript? Só outro nome pra observadores. E o React e todo o conceito de UI reativa? Apenas observadores do DOM. E não para por aí! Sistemas pub/sub? Uma notificação aqui, uma atualização ali... apenas observadores rebatizados de novo.

No fim, o Observer é o verdadeiro pilar invisível por trás de toda a computação "async moderna."

Como eu sempre gosto de dizer, toda essa “falácia do moderno” – no fundo, sempre é a mesma coisa ;)

Um abraço e bons estudos.

1

Muito útil o observer, sempre utilizo no Laravel de forma fácil. Um exemplo é quando quero criar um slug único baseado ao título de um post, por exemplo. No observer, declaro que após criar o model, gere o slug e concatene com id do registro no banco. Muito simples e eficaz.

public function created(Post $post)
{
    // gera o slug e concatena com o id
    $post->slug = Str::slug($post->titulo) . "-{$post->titulo}";
    $post->save();
}
0