티스토리 뷰

공부/디자인 패턴

옵저버 패턴

-=HaeJuK=- 2024. 3. 5. 20:26
728x90

옵저버 패턴(Observer Pattern)

옵저버 패턴(Observer Pattern)은 행동 디자인 패턴 중 하나로, 객체의 상태 변화를 관찰하고 이러한 변화에 대해 하나 이상의 관찀자에게 자동으로 알림을 보내는 패턴입니다. 이 패턴은 주로 분산 이벤트 처리 시스템, GUI 툴, 리액티브 프로그래밍에서 널리 사용됩니다. C/C++ 언어를 사용하는 리눅스 환경에서도 옵저버 패턴을 구현할 수 있으며, 이는 이벤트 기반의 프로그래밍 모델을 구축할 때 유용합니다.

옵저버 패턴의 주요 구성 요소는 다음과 같습니다:

  • Subject (주제): 관찰 대상 객체로, 여러 관찰자(Observer) 객체를 자신의 리스트에 유지하고, 자신의 상태 변화를 이들 관찰자에게 알립니다.
  • Observer (관찰자): 주제의 상태 변화를 관찰하는 객체로, 주제로부터 상태 변화를 통보받을 때 반응하는 업데이트 메서드를 구현합니다.
  • ConcreteSubject (구체적 주제): Subject 인터페이스를 구현하거나 확장하여, 자신의 상태를 저장하고 관찰자에게 상태 변경을 알리는 메서드를 구현합니다.
  • ConcreteObserver (구체적 관찰자): Observer 인터페이스를 구현하거나 확장하여, 주제로부터 상태 변화의 알림을 받고, 필요한 동작을 수행합니다.

옵저버 패턴을 C/C++에서 구현하는 기본적인 방법은 다음과 같습니다:

  1. Observer 인터페이스 정의: 상태 변화에 대한 반응으로 호출될 메서드(예: update())를 포함하는 인터페이스를 정의합니다.
  2. Subject 클래스 구현: Observer 객체들의 리스트를 유지하고, 상태 변화가 있을 때 이들에게 알리는 메서드(notifyObservers())를 구현합니다. 또한 Observer를 추가(attach())하거나 제거(detach())하는 메서드도 포함해야 합니다.
  3. ConcreteObserver 클래스 구현: Observer 인터페이스를 구현하며, update() 메서드에서는 주제로부터 통지받은 정보를 바탕으로 필요한 처리를 수행합니다.
  4. ConcreteSubject 클래스 구현: 필요한 비즈니스 로직과 상태 관리를 수행하며, 상태가 변경될 때 notifyObservers() 메서드를 호출하여 관찰자들에게 변경 사실을 알립니다.

옵저버 패턴은 유연한 설계를 가능하게 하여, 시스템의 여러 부분 사이의 결합도를 낮추고, 변화에 대응하기 쉽게 만들어 줍니다. 리눅스에서 C/C++을 사용하여 개발할 때, 이벤트 드리븐 프로그램이나 GUI 애플리케이션 등에서 옵저버 패턴을 활용할 수 있습니다.

 

이 예제에서는 주제(Subject)로서의 NewsAgency 클래스와 관찰자(Observer)로서의 NewsSubscriber 클래스를 구현합니다. NewsAgency는 뉴스를 업데이트할 때마다 모든 구독자에게 최신 뉴스를 알리는 역할을 합니다.

#include <iostream>
#include <list>
#include <string>

// Observer 인터페이스
class Observer {
public:
    virtual ~Observer() {}
    virtual void update(const std::string& news) = 0;
};

// Subject 클래스
class NewsAgency {
private:
    std::list<Observer*> observers;
    std::string news;
public:
    void addObserver(Observer* observer) {
        observers.push_back(observer);
    }

    void removeObserver(Observer* observer) {
        observers.remove(observer);
    }

    void setNews(const std::string& news) {
        this->news = news;
        notifyObservers();
    }

    void notifyObservers() {
        for (Observer* observer : observers) {
            observer->update(news);
        }
    }
};

// ConcreteObserver 클래스
class NewsSubscriber : public Observer {
private:
    std::string name;
public:
    NewsSubscriber(const std::string& name) : name(name) {}

    void update(const std::string& news) override {
        std::cout << name << " received news: " << news << std::endl;
    }
};

int main() {
    NewsAgency agency;

    NewsSubscriber subscriber1("Subscriber 1");
    NewsSubscriber subscriber2("Subscriber 2");

    agency.addObserver(&subscriber1);
    agency.addObserver(&subscriber2);

    agency.setNews("Breaking News: C++ Observer Pattern Example");

    agency.removeObserver(&subscriber2);

    agency.setNews("Update: C++ Observer Pattern Example Completed");

    return 0;
}

이 예제의 주요 특징은 다음과 같습니다:

  • Observer는 관찰자 인터페이스이며, 모든 구체적 관찰자는 이 인터페이스를 구현해야 합니다. 여기서는 update() 메서드를 통해 뉴스를 업데이트 받습니다.
  • NewsAgency는 뉴스 기사를 관리하고, 새로운 뉴스가 생길 때마다 등록된 모든 관찰자들(NewsSubscriber)에게 알립니다.
  • NewsSubscriber는 구체적 관찰자로서, NewsAgency로부터 뉴스 업데이트를 받아 사용자에게 표시합니다.
  • main 함수에서는 NewsAgency 객체를 생성하고, 두 개의 NewsSubscriber 객체를 관찰자로 등록한 다음, 뉴스를 업데이트하여 이를 관찰자들이 받아볼 수 있도록 합니다.
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함
250x250