Menu
Coddy logo textTech

Padrão Observer

Parte da seção Object Oriented Programming do Journey de Python da Coddy — lição 47 de 64.

O Padrão Observer cria um relacionamento de um para muitos onde um objeto (sujeito) notifica múltiplos objetos (observadores) quando seu estado muda.

Aqui está uma classe Subject simples que gerencia observadores:

class Subject:
    def __init__(self):
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def notify(self, message):
        for observer in self._observers:
            observer.update(message)

O sujeito mantém uma lista de observadores e pode notificá-los todos de uma vez.

Crie classes observadoras simples:

class EmailNotifier:
    def update(self, message):
        print(f"Email sent: {message}")

class SMSNotifier:
    def update(self, message):
        print(f"SMS sent: {message}")

Cada observador possui um método update que é chamado quando notificado.

Use o padrão observer:

# Create subject
news = Subject()

# Create observers
email = EmailNotifier()
sms = SMSNotifier()

# Add observers to subject
news.add_observer(email)
news.add_observer(sms)

# Notify all observers
news.notify("Breaking news: Python is awesome!")

Crie um exemplo prático com um rastreador de preços de ações:

class Stock:
    def __init__(self, symbol, price):
        self.symbol = symbol
        self._price = price
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def set_price(self, price):
        self._price = price
        self.notify()
    
    def notify(self):
        for observer in self._observers:
            observer.update(self.symbol, self._price)

class Investor:
    def __init__(self, name):
        self.name = name
    
    def update(self, symbol, price):
        print(f"{self.name} notified: {symbol} is now ${price}")

# Use the stock tracker
apple_stock = Stock("AAPL", 150)

investor1 = Investor("Alice")
investor2 = Investor("Bob")

apple_stock.add_observer(investor1)
apple_stock.add_observer(investor2)

apple_stock.set_price(155)  # Notifies all investors

Saída:

Email sent: Breaking news: Python is awesome!
SMS sent: Breaking news: Python is awesome!
Alice notified: AAPL is now $155
Bob notified: AAPL is now $155

Ponto Chave: O Padrão Observer permite que um objeto notifique muitos outros automaticamente quando algo muda. O sujeito mantém uma lista de observadores e chama seu método update quando necessário. Isso é útil para notificações, sistemas de eventos e para manter múltiplas partes da sua aplicação sincronizadas.

challenge icon

Desafio

Médio

Implemente o Padrão Observer criando um sistema de monitoramento meteorológico. Você precisa criar duas classes nas áreas designadas do código.

Passo 1: Criar a classe WeatherStation

Escreva sua classe WeatherStation onde o comentário indica. Esta classe deve:

  • Herdar da classe Subject (use class WeatherStation(Subject):)
  • Inicializar com:
    • Chamar o construtor pai usando super().__init__()
    • Definir a temperatura inicial como 0 usando um atributo privado self._temperature
  • Implementar <strong>set_temperature(self, temperature)</strong>:
    • Atualizar o atributo de temperatura privado
    • Chamar self.notify(self._temperature) para notificar todos os observadores
  • Implementar <strong>get_temperature(self)</strong>:
    • Retornar o valor da temperatura atual

Passo 2: Criar a classe WeatherDisplay

Escreva sua classe WeatherDisplay onde o comentário indica. Esta classe deve:

  • Herdar da classe Observer (use class WeatherDisplay(Observer):)
  • Inicializar com:
    • Aceitar um parâmetro name
    • Armazenar o nome como self.name
  • Implementar <strong>update(self, temperature)</strong>:
    • Imprimir a mensagem de atualização de temperatura no formato exato mostrado abaixo

Formato da Mensagem:

Quando um display recebe uma atualização de temperatura, ele deve imprimir exatamente:

Display [name]: Current temperature is [temperature]C

Exemplo de Uso:

# Create weather station and displays
station = WeatherStation()
phone_display = WeatherDisplay("Phone")
tablet_display = WeatherDisplay("Tablet")

# Attach displays to station
station.attach(phone_display)
station.attach(tablet_display)

# Update temperature - both displays will be notified
station.set_temperature(25.5)

# Output:
# Display Phone: Current temperature is 25.5C
# Display Tablet: Current temperature is 25.5C

Notas Importantes:

  • Os métodos attach() e detach() já estão implementados na classe base Subject - você não precisa implementá-los ou chamá-los em sua classe WeatherStation
  • No exemplo de uso acima, station.attach(phone_display) é chamado pelo usuário da sua classe, não dentro da sua implementação de WeatherStation
  • Sua WeatherStation só precisa chamar self.notify() quando a temperatura mudar - a classe base Subject cuida do resto
  • Foque em implementar os três métodos exigidos em WeatherStation e os dois métodos exigidos em WeatherDisplay conforme especificado acima

Folha de consulta

O Padrão Observer cria um relacionamento de um-para-muitos onde um objeto (sujeito) notifica múltiplos objetos (observadores) quando seu estado muda.

Classe Subject básica que gerencia observadores:

class Subject:
    def __init__(self):
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def notify(self, message):
        for observer in self._observers:
            observer.update(message)

Classes Observer com o método update:

class EmailNotifier:
    def update(self, message):
        print(f"Email sent: {message}")

class SMSNotifier:
    def update(self, message):
        print(f"SMS sent: {message}")

Usando o padrão observer:

# Criar sujeito
news = Subject()

# Criar observadores
email = EmailNotifier()
sms = SMSNotifier()

# Adicionar observadores ao sujeito
news.add_observer(email)
news.add_observer(sms)

# Notificar todos os observadores
news.notify("Breaking news: Python is awesome!")

Exemplo prático com um rastreador de preços de ações:

class Stock:
    def __init__(self, symbol, price):
        self.symbol = symbol
        self._price = price
        self._observers = []
    
    def add_observer(self, observer):
        self._observers.append(observer)
    
    def set_price(self, price):
        self._price = price
        self.notify()
    
    def notify(self):
        for observer in self._observers:
            observer.update(self.symbol, self._price)

class Investor:
    def __init__(self, name):
        self.name = name
    
    def update(self, symbol, price):
        print(f"{self.name} notified: {symbol} is now ${price}")

O Padrão Observer permite que um objeto notifique muitos outros automaticamente quando algo muda. O sujeito mantém uma lista de observadores e chama seu método update quando necessário.

Experimente você mesmo

class Subject:
    def __init__(self):
        self._observers = []
    
    def attach(self, observer):
        self._observers.append(observer)
        
    def detach(self, observer):
        self._observers.remove(observer)
        
    def notify(self, data):
        for observer in self._observers:
            observer.update(data)
            
class Observer:
    def update(self, data):
        pass

# Escreva sua classe WeatherStation aqui

# Escreva sua classe WeatherDisplay aqui

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 Object Oriented Programming