Menu
Coddy logo textTech

Padrão Observer

Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy. Lição 73 de 91.

O padrão Observer é um padrão comportamental de projeto que estabelece uma relação de um para muitos entre objetos. Quando um objeto (o sujeito) muda de estado, todos os seus dependentes (os observadores) são automaticamente notificados e atualizados.

Pense em uma assinatura de newsletter. A newsletter é o sujeito, e os assinantes são observadores. Quando uma nova edição é publicada, todos os assinantes a recebem automaticamente, sem que a newsletter precise conhecer os detalhes de cada assinante.

Aqui está uma implementação básica em PHP:

<?php
interface Observer {
    public function update(string $message): void;
}

class Newsletter {
    private array $subscribers = [];
    
    public function subscribe(Observer $observer): void {
        $this->subscribers[] = $observer;
    }
    
    public function publish(string $content): void {
        foreach ($this->subscribers as $subscriber) {
            $subscriber->update($content);
        }
    }
}

class EmailSubscriber implements Observer {
    public function __construct(private string $email) {}
    
    public function update(string $message): void {
        echo "Sending to {$this->email}: $message\n";
    }
}

$newsletter = new Newsletter();
$newsletter->subscribe(new EmailSubscriber("alice@example.com"));
$newsletter->subscribe(new EmailSubscriber("bob@example.com"));
$newsletter->publish("New article released!");

Saída:

Sending to alice@example.com: New article released!
Sending to bob@example.com: New article released!

O padrão desacopla o assunto de seus observadores. A classe Newsletter não precisa saber se está notificando assinantes de e-mail, assinantes de SMS ou serviços de notificações push. Ela simplesmente chama update() em qualquer elemento que implemente a interface Observer. Isso torna fácil adicionar novos tipos de observadores sem modificar o código existente.

challenge icon

Desafio

Fácil

Vamos criar um sistema de alertas de preço de ações usando o Padrão Observer. Quando o preço de uma ação muda, todos os investidores registrados devem ser notificados automaticamente: uma aplicação perfeita desse padrão no mundo real.

Você organizará seu código em quatro arquivos:

  • Observer.php: Defina uma interface Observer com um único método update(string $stockName, float $price): void. Esse é o contrato que todos os observadores devem seguir para receber notificações.
  • Investors.php: Inclua o arquivo Observer e crie duas classes que implementem a interface:
    • EmailInvestor: Recebe um endereço de e-mail em seu construtor (use a promoção de propriedades no construtor). Seu método update() imprime "Email to [email]: [stockName] is now $[price]"
    • SmsInvestor: Recebe um número de telefone em seu construtor. Seu método update() imprime "SMS to [phone]: [stockName] is now $[price]"
  • Stock.php: Inclua o arquivo Observer e crie uma classe Stock que atua como o assunto. Sua ação deve:
    • Armazenar o nome da ação e o preço atual (use a promoção de propriedades no construtor para o nome e inicialize o preço como 0.0)
    • Manter um array privado de observadores
    • Ter um método subscribe(Observer $observer): void para adicionar observadores
    • Ter um método setPrice(float $price): void que atualiza o preço e notifica todos os observadores
    Ao notificar os observadores, chame o método update() de cada observador com o nome da ação e o novo preço.
  • main.php: Inclua os arquivos Investors e Stock. Você receberá três entradas: um nome de ação, um endereço de e-mail e um número de telefone.

    Crie um Stock com o nome fornecido. Inscreva um EmailInvestor com o endereço de e-mail e um SmsInvestor com o número de telefone.

    Defina o preço da ação como 150.50 para acionar notificações para todos os inscritos.

O Padrão Observer mantém sua classe Stock desacoplada dos métodos específicos de notificação. Você poderia facilmente adicionar um PushInvestor ou SlackInvestor mais tarde sem modificar a classe Stock.

Experimente você mesmo

<?php
require_once 'Investors.php';
require_once 'Stock.php';

// Ler entradas
$stockName = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$phone = trim(fgets(STDIN));

// TODO: Crie um Stock com o nome fornecido

// TODO: Inscreva um EmailInvestor com o endereço de e-mail

// TODO: Inscreva um SmsInvestor com o número de telefone

// TODO: Defina o preço do stock para 150.50 para acionar as notificações
?>
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de PHP online