카테고리 없음

[디자인 패턴] Observer 패턴이란? - 개발 경험

yongyongcoding 2025. 2. 16. 18:20

 

Observer 패턴이란 일대다 관계에서 주로 사용되며 객체의 상태 변화를 다른 객체들에 알릴 때 사용되는 디자인 패턴이다. 소켓에 대해 프로그래밍을 하던 도중 디자인 패턴이라는 개념을 접하게 되었다.

내가 개발하던 프로그램은 "소켓을 이용한 클라이언트 간 메세지 송수신 프로그램"이었다.

 

어떻게 클라이언트의 메세지를 보내고 받을 수 있을까?

이 때 사용했던 디자인 패턴이  바로 옵저버 패턴였다.

 

 


 

옵저버 패턴의 구조는 크게 3가지로 구성되어있다.

1. 이벤트를 발생시키는 객체인 주체(Subject)

2. 주체의 상태를 변화하고 감지하고 반응하는 객체인 옵저버(Observer)

3. 옵저버의 행동을 담당하는 액션(Action)

 

 

그렇다면 클라이언트가 메세지 보내는 과정을 옵저버 패턴에 적용하면?

1. 클라이언트가 메세지를 송신 때 주체( Subject )에 알려준다.

2. 메세지 송신 신호를 받은 주체( Subject )는 신호(송신, 수신)로 등록된 옵저버( Observer )에 알림을 준다.

3. 알림을 받은 송신 옵저버( Observer )는 송신 신호를 받고 메세지를 보내준다. (update)

 

 

이러한 옵저버 패턴 예시를 일반화 하면 다음과 같아

1. 클라이언트로부터 주체의 상태가 변경된다. (ex) .receiveMessage (), .sendMessage() )

2. 주체의 상태 변화를 주체에 등록된 옵저버들에 알림을 준다.(notify)

3. 각 옵저버는 변경 사항을 반영한다. (update)

 

 

여기서 나는 의문이 있었다.

왜? 클라이언트에서 바로 send동작을 하고 receive 동작을 하면 되는데 굳이 옵저버 패턴을 거쳐야할까?

이 해답은 구조를 통해 깨달았다.

Subject -> Observer -> Action 순으로 자동으로 동작.

 

위의 이미지를 보면 옵저버 패턴의 각 구성요소들이 인터페이스로 구현된 모습을 띄고 있다.

이는 의존성 주입을 통해 유지 보수에 용이하도록 만들어진 패턴인 것이다.

쉽게 말해 Subject와 Observer가 독립적으로 작동하며 상태가 변화했을 때 Subject를 통해 

send나 receive함수만 호출해주면 옵저버들이 변경사항을 자동으로 업데이트할 수 있게 되기 때문이다.

또한 인터페이스에 의존하기 때문에 확장성에도 큰 이점을 갖을 수 있다.

 

 옵저버 패턴의 장/단점

장점 : 

- 유지 보수에 용이 : Subject와 Observer가 독립적으로 동작 가능

- 자동 알림 : 상태 변화가 발생하면 Subject는 Observer를 Observer는 Action을 자동 호출해준다.

- 확장성 : 새로운 옵저버 추가/삭제 시 Subject 코드 변경 X 

 

단점 : 

- 성능 문제 : 위에서 의문을 가졌듯이 바로 서버를 호출할 수 있는데 모든 옵저버를 순회하면 호출하기 때문에 성능이 저하될 수 있다.

- 디버깅 어려움 : 이벤트 흐름이 명시적이지 않기 때문에 디버깅에 어려움이 있다.

 

 

 


따라서 옵저버 패턴은 상황에 맞게 사용하는 것이 중요할 것 같은데
고객마다 적용 Level(BASIC, VIP, VVIP ... )이나 적용 쿠폰이 다를 경우,
객체당 처리해야할 동작이 많을 경우,
고객들에게 상품이 재입고 되었을 때 알리는 경우,
GUI의 이벤트 리스너 등
아주 유용하고 프로젝트의 단단한 구조로서 사용할 수 있을것같다.

 

 

 

※ 참고 : 아래는 옵저버 패턴의 간단한 인터페이스 구조이다. 

// 주체 (Publisher, Subject)
interface Subject {
    void attach(Observer observer); // 옵서버 등록
    void detach(Observer observer); // 옵서버 제거
    void notifyObservers(); // 상태 변경 알림
}

// 옵서버 (Subscriber, Listener)
interface Observer {
    void update(String message); // 상태 변경을 전달받음
}

// 동작 (Action)
interface MessageAction {
    void execute(String message);
}