옵서버: 바뀐 내용을 구독자에게 알리기
재고가 바뀌면 화면과 기록 장치에 알려야 합니다. 재고 객체 안에 모든 화면 종류를 적어 두는 대신, 알림받을 함수를 등록하도록 만들 수 있습니다. 이것이 옵서버 패턴의 기본 발상입니다.
등록, 통지, 해제
class Stock:
def __init__(self):
self.quantity = 0
self.listeners = []
def subscribe(self, listener):
self.listeners.append(listener)
def unsubscribe(self, listener):
self.listeners.remove(listener)
def set_quantity(self, quantity):
self.quantity = quantity
for listener in list(self.listeners):
listener(quantity)
def show(quantity):
print("stock:", quantity)
stock = Stock()
stock.subscribe(show)
stock.set_quantity(3)
stock.unsubscribe(show)
stock.set_quantity(2)
출력은 stock: 3 한 번입니다. 구독을 해제한 뒤 바꾼 재고 2는 출력하지 않습니다. 통지할 때 목록을 복사하므로, 콜백이 구독 목록을 바꾸어도 현재 순회의 대상이 갑자기 달라지지 않습니다.
알림 정책도 설계의 일부입니다
예제는 등록 순서대로 같은 실행 흐름에서 콜백을 부릅니다. 옵서버라고 자동으로 비동기 처리되는 것은 아닙니다. 한 구독자가 느리거나 오류를 내면 다른 구독자에게도 영향을 줄 수 있습니다. 오류를 전파할지, 개별적으로 기록하고 계속할지 정책을 정해야 합니다.
화면이 사라질 때 구독을 해제하지 않으면 필요 없는 객체가 남거나 중복 알림을 받을 수 있습니다. 반대로 알림을 받은 쪽이 다시 값을 바꾸면 반복 통지가 생길 수 있습니다.
확인 문제
같은 화면을 열 때마다 콜백을 새로 등록했는데 닫을 때 해제하지 않았습니다. 어떤 증상이 생길 수 있을까요?
해설 보기
한 번의 변경에 같은 동작이 여러 번 실행되거나 닫힌 화면이 계속 참조될 수 있습니다. 구독을 시작한 곳과 끝내는 곳을 짝지어 관리해야 합니다.