Menu
Coddy logo textTech

옵저버 패턴

Coddy Python 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 64개 중 47번째.

옵저버 패턴은 하나의 객체(subject)의 상태가 변경될 때 여러 객체(observers)에게 알림을 보내는 일대다(one-to-many) 관계를 생성합니다.

다음은 옵저버들을 관리하는 간단한 Subject 클래스입니다:

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)

주제(Subject)는 옵저버 목록을 유지하며, 이들 모두에게 한 번에 알림을 보낼 수 있습니다.

간단한 옵저버 클래스를 생성합니다:

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

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

각 옵저버는 알림을 받을 때 호출되는 update 메서드를 가집니다.

옵저버 패턴을 사용하세요:

# 주제(subject) 생성
news = Subject()

# 옵저버(observer) 생성
email = EmailNotifier()
sms = SMSNotifier()

# 주제에 옵저버 추가
news.add_observer(email)
news.add_observer(sms)

# 모든 옵저버에게 알림
news.notify("Breaking news: Python is awesome!")

주식 가격 추적기를 사용한 실용적인 예제를 만들어 보겠습니다:

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}")

# 주식 추적기 사용
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)  # 모든 투자자에게 알림을 보냅니다

출력:

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

핵심 포인트: 옵저버 패턴(Observer Pattern)은 어떤 변화가 발생했을 때 하나의 객체가 다른 여러 객체에게 자동으로 알림을 보낼 수 있게 해줍니다. 주체(Subject)는 옵저버 목록을 유지하며, 필요할 때 그들의 update 메서드를 호출합니다. 이는 알림, 이벤트 시스템, 그리고 애플리케이션의 여러 부분을 동기화된 상태로 유지하는 데 유용합니다.

challenge icon

챌린지

중급

기상 모니터링 시스템을 만들어 옵저버 패턴(Observer Pattern)을 구현하세요. 코드의 지정된 영역에 두 개의 클래스를 생성해야 합니다.

1단계: WeatherStation 클래스 생성

주석이 표시된 위치에 WeatherStation 클래스를 작성하세요. 이 클래스는 다음을 수행해야 합니다.

  • Subject 클래스 상속 (class WeatherStation(Subject): 사용)
  • 초기화:
    • super().__init__()을 사용하여 부모 생성자 호출
    • 프라이빗 속성인 self._temperature를 사용하여 초기 온도를 0으로 설정
  • <strong>set_temperature(self, temperature)</strong> 구현:
    • 프라이빗 온도 속성 업데이트
    • self.notify(self._temperature)를 호출하여 모든 옵저버에게 알림
  • <strong>get_temperature(self)</strong> 구현:
    • 현재 온도 값을 반환

2단계: WeatherDisplay 클래스 생성

주석이 표시된 위치에 WeatherDisplay 클래스를 작성하세요. 이 클래스는 다음을 수행해야 합니다.

  • Observer 클래스 상속 (class WeatherDisplay(Observer): 사용)
  • 초기화:
    • name 파라미터를 받음
    • 이름을 self.name으로 저장
  • <strong>update(self, temperature)</strong> 구현:
    • 아래에 표시된 정확한 형식으로 온도 업데이트 메시지를 출력

메시지 형식:

디스플레이가 온도 업데이트를 받으면 반드시 다음과 같이 출력해야 합니다.

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

사용 예시:

# 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

중요 참고 사항:

  • attach()detach() 메서드는 이미 Subject 베이스 클래스에 구현되어 있습니다. WeatherStation 클래스에서 이를 구현하거나 호출할 필요가 없습니다.
  • 위의 사용 예시에서 station.attach(phone_display)는 WeatherStation 구현 내부가 아니라 클래스 사용자에 의해 호출됩니다.
  • WeatherStation은 온도가 변할 때 self.notify()를 호출하기만 하면 됩니다. 나머지는 Subject 베이스 클래스가 처리합니다.
  • 위에 명시된 대로 WeatherStation의 필수 메서드 3개와 WeatherDisplay의 필수 메서드 2개를 구현하는 데 집중하세요.

치트 시트

옵저버 패턴(Observer Pattern)은 하나의 객체(주체, subject)의 상태가 변경될 때 여러 객체(관찰자, observers)에게 알림을 보내는 일대다 관계를 생성합니다.

관찰자들을 관리하는 기본 Subject 클래스:

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)

update 메서드를 가진 관찰자(Observer) 클래스들:

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

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

옵저버 패턴 사용하기:

# 주체 생성
news = Subject()

# 관찰자 생성
email = EmailNotifier()
sms = SMSNotifier()

# 주체에 관찰자 추가
news.add_observer(email)
news.add_observer(sms)

# 모든 관찰자에게 알림
news.notify("Breaking news: Python is awesome!")

주가 추적기를 활용한 실용적인 예제:

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}")

옵저버 패턴을 사용하면 무언가 변경될 때 하나의 객체가 다른 여러 객체에게 자동으로 알림을 보낼 수 있습니다. 주체는 관찰자 목록을 유지하며 필요할 때 그들의 update 메서드를 호출합니다.

직접 해보기

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

# 여기에 WeatherStation 클래스를 작성하세요

# 여기에 WeatherDisplay 클래스를 작성하세요

quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Object Oriented Programming의 모든 레슨