본문 바로가기
까망 동네/디자인 패턴

[디자인 패턴] 관찰자(Observer) 패턴

by 까망 하르방 2023. 11. 6.
반응형

🎈 감시자 패턴 (Observer Pattern)

• 어떤 객체 상태가 변경되면 다른 객체(observer)에게 알리는 디자인 패턴

 → 의존관계에 있는 모든 객체들이 통지받고 자동으로 갱신

 → 1:多 형태로 Broadcast로 활용

• 옵저버(Observer) 패턴은 객체 간 느슨한 결합 제공

• 데이터 흐름을 관찰하여 분산 이벤트 처리에 유용

 → GUI 프레임워크, 게임 엔진, 주식 시장 알림, 예외 처리와 로깅, 발행/구독

• 디자인 패턴 중 행위 패턴에 해당된다.

 

💻 디자인 패턴(Design Pattern)이란?

👨‍💻 디자인 패턴(Design Pattern)이란? • SW 개발 방법 중에서도 구조적인 문제 해결에 목적을 둔다. • 알고리즘과 같이 특정 문제를 해결하는 Logic 형태보다는 특정 상황에 적용할 수 있는 방

zoosso.tistory.com

 

 

[예제 코드]

#include <iostream>
#include <vector>

class Observer {
public:
    virtual void update(const std::string& message) = 0;
};

class Subject {
private:
    std::vector<Observer*> observers;
    std::string message;

public:
    void addObserver(Observer* observer) {
        observers.push_back(observer);
    }

    void setMessage(const std::string& newMessage) {
        message = newMessage;
        notifyObservers();
    }

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

class ConcreteObserver : public Observer {
public:
    ConcreteObserver(const std::string& name) : name(name) {}


    void update(const std::string& message) override {
        std::cout << "[수신] " << name << ": "  << message << std::endl;
    }

private:
    std::string name;
};

int main() {
    Subject subject;
    ConcreteObserver observer1("Observer 1");
    ConcreteObserver observer2("Observer 2");

    subject.addObserver(&observer1);
    subject.addObserver(&observer2);

    subject.setMessage("Hello, observers!");

    return 0;
}

 

감시자 패턴 예시 결과

 

Subject 클래스는 관찰 대상이 되는 객체로

Observer 클래스는 관찰자 객체를 나타낸다.

Subject가 상태 변경을 감지하면 등록된 모든 옵저버에게 업데이트 통지한다.

 

 

🎈 감시자 패턴 장단점

+  Overhead 발생 최소화:

 상황에 따라 등록된 Object들에게 notify 해주기 때문에

 대상 변화 감지하기 위해 Observer들이 주기적으로 접근하지 않아도 된다.

 

 

🎈 구현시 주의사항

✔️ 옵저버 패턴에서는 불필요한 업데이트 여부

✔️ 다수의 감시자 등록으로 메모리 Overhead 발생 여부

 

 

[예제 코드]

#include <iostream>
#include <vector>

class Observer {
public:
    virtual void handleEvent(const std::string& event) = 0;
};

// Subject class
class Button {
private:
    std::vector<Observer*> observers;
    std::string label;

public:
    Button(const std::string& label) : label(label) {}

    void addObserver(Observer* observer) {
        observers.push_back(observer);
    }

    void removeObserver(Observer* observer) {
        // Remove observer implementation here (not shown in this example).
    }

    void click() {
        std::string event = label;
        notifyObservers(event);
    }

    void notifyObservers(const std::string& event) {
        for (Observer* observer : observers) {
            observer->handleEvent(event);
        }
    }
};

// Concrete Observer class
class ClickHandler : public Observer {
public:
    ClickHandler(const std::string& name) : name(name) {}

    void handleEvent(const std::string& event) override {
        std::cout << "["  << name << "]: " << event << std::endl;
    }

private:
    std::string name;
};

int main() {
    Button button("[Button Event]");

    ClickHandler handler1("Handler 1");
    ClickHandler handler2("Handler 2");

    // 핸들러 등록
    button.addObserver(&handler1);
    button.addObserver(&handler2);

    button.click();

    return 0;
}

 

감시자 패턴 예시 결과

 

UI 프레임워크에서 버튼 클릭, 마우스 이동, 키보드 입력 등의 이벤트 처리할 때

옵저버 패턴을 활용해볼 수 있다.

 

버튼 객체가 클릭되면,

등록된 모든 관찰자에게 이벤트를 알리고 처리한다.

 

메시지를 추가할 때

자동으로 옵저버에게 알릴 수 있으므로 유지보수가 쉽다.


 

🎈 다른 디자인 패턴과 비교

• 퍼사드 (Facade)

객체 간 상호작용을 단순화하고 인터페이스를 제공하는 것이 비슷하지만

퍼사드 패턴은 서브시스템의 복잡성을 숨기고

클라이언트에게 간단한 통합 인터페이스를 제공하는 것이 목적이다.

 

[디자인패턴] 퍼사드 패턴 (Facade Pattern)

🎈 퍼사드 패턴 (Facade Pattern) • 복잡한 시스템을 단순화된 인터페이스를 제공하여 사용자가 시스템 일부분을 쉽게 사용할 수 있도록 한다. • 디자인 패턴 중 구조 패턴에 해당된다. 💻 디자인

zoosso.tistory.com

 

 

• 상태 (State)

객체 내부 상태가 변경될 때 행동을 변경시키는 패턴

 

상태 패턴 (State Pattern)

상태(State) 패턴이란? • 객체 내부 상태에 맞춰 스스로 행동을 변경하는 패턴 • 객체는 마치 자신의 클래스를 바꾸는 것처럼 보인다. • if-else와 같은 분기문으로 상태전이 하는 것을 해소한다.

zoosso.tistory.com

 

 

• 중재자 (Mediator)

객체 상호작용을 관리하는 것에 중재자 패턴과 유사하다.

하지만 감시자 패턴은 1:N 관계로 상태변화를 관찰자에게 통보한다. 

반면 중재자는 객체간의 직접 통신을 방지하며 중재자 객체를 통해 통신한다

 

[디자인 패턴] 중재자 패턴 (Mediator Pattern)

🎈 중재자 패턴 (Mediator Pattern) • 객체들이 직접 서로 참조하지 않도록 하여 객체들간 느슨한 결합 유지 • 객체들의 상호작용을 독립적으로 다양화 시킨다. • 디자인 패턴에서 행위 패턴에 속

zoosso.tistory.com

반응형

댓글