Chương 11 — Observer Pattern

Observer pattern — kiến trúc

Các thành phần của observer pattern

Key idea 1: Sơ đồ cấu trúc

Subject (interface)           Observer (interface)
  + attach(observer)            + update(subject)
  + detach(observer)
  + notify()
       ^                               ^
       |                               |
ConcreteSubject             ConcreteObserver
  - state                    (aggregates Subject)
  - observers: list

Subject interface:

from abc import ABC, abstractmethod

class Subject(ABC):
    @abstractmethod
    def attach(self, observer: 'Observer'):
        pass

    @abstractmethod
    def detach(self, observer: 'Observer'):
        pass

    @abstractmethod
    def notify(self):
        pass

Observer interface:

class Observer(ABC):
    @abstractmethod
    def update(self, subject: Subject):
        pass

Key idea 2: ConcreteSubject

class ConcreteSubject(Subject):
    def __init__(self):
        self._observers: list[Observer] = []
        self._state = None

    def attach(self, observer: Observer):
        self._observers.append(observer)

    def detach(self, observer: Observer):
        self._observers.remove(observer)

    def notify(self):
        for observer in self._observers:
            observer.update(self)

    def set_state(self, state):
        self._state = state
        self.notify()  # Thông báo khi state thay đổi

    def get_state(self):
        return self._state

Key idea 3: ConcreteObserver

class ConcreteObserver(Observer):
    def __init__(self, name: str):
        self._name = name

    def update(self, subject: Subject):
        print(f"{self._name} received update: {subject.get_state()}")

Key idea 4: Mẫu sử dụng chuẩn

subject = ConcreteSubject()

obs_a = ConcreteObserver("Observer A")
obs_b = ConcreteObserver("Observer B")

subject.attach(obs_a)
subject.attach(obs_b)

subject.set_state("new_state")
# >> observer a received update: new_state
# >> observer b received update: new_state

subject.detach(obs_a)
subject.set_state("another_state")
# >> observer b received update: another_state
# (observer a không còn nhận thông báo)

Key idea 5: Push vs Pull model

Model Mô tả Ưu điểm
Push Subject gửi dữ liệu vào update(data) Observer không cần giữ reference đến Subject
Pull Observer nhận Subject và tự lấy dữ liệu Observable kiểm soát dữ liệu nào cần lấy

Cách triển khai trên dùng Pull model — Observer nhận Subject và gọi get_state().

Đăng ký nhận Newsletter
Cập nhật bài viết mới nhất!