개발하는 리프터 꽃게맨입니다.

[C++/디자인패턴] 옵저버 패턴 (Observer) 본문

기타 개발 지식/디자인패턴

[C++/디자인패턴] 옵저버 패턴 (Observer)

파워꽃게맨 2024. 1. 29. 13:31

1. 개요

삐삐쀼쀼

 

옵저버 (혹은 관찰자, 리스너) 패턴은 객체의 상태 변화를 관찰하는 관찰자를 두어,

어떤 객체의 상태가 변하면, 그와 연관된 객체들에게 알림을 보내는 패턴입니다.

 

옵저버 패턴을 활용하면 연관된 객체가 어떤 객체의 상태가 변할시

별도의 함수 호출 없이 즉각적으로 알 수 있기 때문에, 이벤트에 대한 처리를 해야할 경우 유용하게 사용됩니다.

 

예를들어 플레이어가 열쇠 4개를 모으면 문이 열리는 게임이 존재한다고 해봅시다.

플레이어가 문에 대한 정보를 알고있고 문에대해서 직접 이벤트를 처리해주는 것은 OOP 의 설계 원칙과는 맞지 않습니다. 플레이어가 홀로 너무 많은 일을 떠맡고 있는 것이죠.

 

그래서 플레이어에게 옵저버를 두어, 플레이어가 열쇠를 획득할 때마다

옵저버들에게 열쇠를 획득했다고 알리는 설계를 생각해볼 수 있습니다.

이것이 옵저버 패턴입니다.

 

2. 기본구조

 

서브젝트에 옵저버를 두어

서브젝트가 상태가 변할시 옵저버에게 notify를 해주는 것이 옵저버 패턴의 핵심입니다.

 

하나의 서브젝트에 여러 개의 옵저버를 둘 수 있기에

1:1 혹은 1:N 의존관계를 가집니다.

 

기본적으로 옵저버는 Notify() 함수를 가집니다.

 

그리고 옵저버를 가지고 있는 Subject라는 클래스가 존재하여

Subject는 옵저버를 붙이고 제거할 수 있고,

Notify 함수를 통해 자신이 가지고 있는 옵저버들에게 Broadcast 형식의 메시지를 보낼 수 있습니다.

 

 

 

3. 예시

옵저버 패턴을 이용해서 개요에서 설명한 게임을 간단하게 만들어보도록 하겠습니다.

 

DoorObserver 가 존재하고,

키가 4개가 모이면 문은 열립니다.

 

 

굳이 필요하지 않아서 Subject 인터페이스는 따로 만들지 않았고,

Player는 현재 맵에 존재하는 Door를 옵저버로 등록해놓고

키를 얻을 때 마다 가지고있는 옵저버들에게 브로트캐스트 메시지를 전달하고 있습니다.

 

 

플레이어코드 어디에도 문을 여는 것에 대한 코드는 없습니다.

그저 '문'이라는 관찰자에게 '나 열쇠 얻었어!' 라고 알려줄 뿐입니다.

 

4. 장단점

장점)

- 실시간으로 한 객체의 변경사항을 다른 객체에 전파할 수 있다.

- 객체간의 의존성을 제거할 수 있다. (느슨한 결합)

 

단점)

- 너무 많이 사용할 경우 상태 관리가 힘들 수 있다.