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 investorsSaí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 $155Ponto 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.
Desafio
MédioImplemente 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
- Chamar o construtor pai usando
- 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
- Aceitar um parâmetro
- 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]CExemplo 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.5CNotas Importantes:
- Os métodos
attach()edetach()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
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
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosO Parâmetro selfMétodosAtributosMétodo Construtor (__init__)Recapitulação - Calculadora Simples4Herança
Herança BásicaA Função super()Sobrescrita de MétodoHerança MúltiplaOrdem de Resolução de MétodosRecapitulação - Hierarquia de Funcionários7Métodos Especiais
Introdução aos Métodos MágicosSobrecarga de OperadoresMétodos Mágicos de ContêinerRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução a Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy2Decoradores
Introdução aos DecoradoresDecorador de PropriedadeDecorador de Método EstáticoDecorador de Método de Classe5Polimorfismo
Sobrescrita de Método RevisitadaDuck TypingClasses e Métodos AbstratosDesign de InterfacesRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição vs HerançaMixinsMétodos Estáticos e de ClasseDecoradores de ClasseGerenciadores de Contexto11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Propriedades de Classe
Variáveis de Instância vs de ClasseDecoradores de PropriedadeAtributos PrivadosRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Membros Públicos, Protegidos e PrivadosModificadores de AcessoOcultação de InformaçãoProperty Decorators AvançadosRecapitulação - Sistema de Registro de Alunos12Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário