🎈 감시자 패턴 (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 Pattern)
🎈 퍼사드 패턴 (Facade Pattern) • 복잡한 시스템을 단순화된 인터페이스를 제공하여 사용자가 시스템 일부분을 쉽게 사용할 수 있도록 한다. • 디자인 패턴 중 구조 패턴에 해당된다. 💻 디자인
zoosso.tistory.com
객체 내부 상태가 변경될 때 행동을 변경시키는 패턴
상태 패턴 (State Pattern)
상태(State) 패턴이란? • 객체 내부 상태에 맞춰 스스로 행동을 변경하는 패턴 • 객체는 마치 자신의 클래스를 바꾸는 것처럼 보인다. • if-else와 같은 분기문으로 상태전이 하는 것을 해소한다.
zoosso.tistory.com
객체 상호작용을 관리하는 것에 중재자 패턴과 유사하다.
하지만 감시자 패턴은 1:N 관계로 상태변화를 관찰자에게 통보한다.
반면 중재자는 객체간의 직접 통신을 방지하며 중재자 객체를 통해 통신한다
[디자인 패턴] 중재자 패턴 (Mediator Pattern)
🎈 중재자 패턴 (Mediator Pattern) • 객체들이 직접 서로 참조하지 않도록 하여 객체들간 느슨한 결합 유지 • 객체들의 상호작용을 독립적으로 다양화 시킨다. • 디자인 패턴에서 행위 패턴에 속
zoosso.tistory.com
'까망 동네 > 디자인 패턴' 카테고리의 다른 글
[디자인 패턴] 메멘토 패턴 (Memento Pattern) (1) | 2023.11.10 |
---|---|
[디자인패턴] 퍼사드 패턴 (Facade Pattern) (54) | 2023.11.09 |
[디자인패턴] 컴포지트 패턴 (Composite Pattern) (1) | 2023.11.05 |
[디자인패턴] 인터프리터 패턴 (Interpreter Pattern) (2) | 2023.11.04 |
[디자인패턴] 커맨드 패턴 (Command Pattern) (1) | 2023.11.03 |
댓글