강께르의 개발일지

[디자인 패턴] 옵저버 패턴 본문

프로그래밍/디자인 패턴

[디자인 패턴] 옵저버 패턴

강께르 2021. 11. 25. 02:47

옵저버 패턴

- 하나의 서브젝트와 다수의 옵저버들 사이의 상호작용을 결합도를 낮게 / 응집도를 높게 만드려는 패턴이다.

- 서브젝트의 일이 일어난다면, 다수의 옵저버들에게 그 일이 발생했다는 것을 알려주고, 옵저버들은 일이 발생했을 때, 처리하고 픈 특정 일을 수행하게 한다.

- 서브젝트 클래스 혹은 인터페이스에는 세가지 기능을 갖고 있다.

 - 옵저버 추가, 옵저버 제거, 옵저버에게 공지

- 추가와 제거하기 위한 데이터 컨테이너를 지니고 있으며, 그 컨테이너를 순회하며 특정 메소드를 호출하는 방식이다.

- 특정 메소드란 옵저버 클래스 혹은 인터페이스가 지니고 있을 메소드를 의미한다.

- 옵저버들은 해당 클래스를 상속받은 클래스를 의미한다. 그 클래스를 상속받은 클래스 인스턴스들은 서브젝트 클래스를 상속받은 클래스 인스턴스의 데이터 컨테이너에 추가되어있을 것이고, 순회하며 자신의 메소드를 호출하게 될 것이다.

 

- 꼭 데이터 컨테이너를 사용하지 않아도 된다. 델리게이트를 사용하여 메소드를 추가하고 델리게이트 변수에 등록된 메소드를 호출하는 방식으로 사용할 수 있다.

 

구현 시 포인트

- 서브젝트 클래스, 인터페이스에선 옵저버 클래스 인스턴스 혹은 메소드를 저장할 데이터 컨테이너 하나와 그 데이터 컨테이너와 관련한 추가, 삭제, 순회 공지 메소드를 구현할 것.

- 옵저버 클래스, 인터페이스는 일괄적으로 호출될 메소드 하나를 구현할 것.

- 서브젝트 클래스는 값 변화가 있어서 그것을 누군가(옵저버)에게 알려주고 픈 클래스로 선정할 것.

- 옵저버 클래스는 특정 클래스 인스턴스의 값 변화에 따라 다르게 동작했으면 좋을 클래스로 선정할 것.

- 예) 플레이어가 체력 50% 이하가 되면 특정 몬스터는 피 냄새를 맡아 분노 모드를 발동시켜야 한다!

플레이어 : 서브젝트 클래스 인스턴스

몬스터 : 옵저버 클래스 인스턴스

체력 50% 이하 : 메소드 호출 조건

분노 모드 : 서브젝트 클래스 인스턴스의 메소드 호출에 따라 옵저버 클래스 인스턴스의 메소드가 호출되어 처리될 작업

 

옵저버 패턴의 장단점

 

장점

- 객체 간의 결합도가 느슨해진다. 결합도는 클래스가 다른 클래스와 연관이 있어 수정을 하면 영향을 주는 부분을 이야기할 수 있다. 앞서 본 옵저버 패턴은 리스트 혹은 델리게이트에 추가된 인스턴스 혹은 등록된 메소드를 순회하며 호출하기 때문에 공통적으로 호출할 메소드가 있다고 보장된 데이터 컨테이너를 사용하고 데이터 컨테이너의 사이즈가 많든 적든 현재 굴리고 있는 서브젝트 클래스 인스턴스에는 영향이 없고 각기 다른 옵저버 클래스 인스턴스끼리도 영향이 없기에 결합도가 낮다고 이야기할 수 있을 것이다.

 

- 결합도가 낮으면서 인스턴스 간의 상호작용함으로 정보 갱신에 용이하다고 한다. 특정 시점에 옵저버에게 호출하여 변화된 값을 넘겨주려는 목적인 패턴이기 때문에 충분히 장점이라고 이야기할 수 있을 것 같다.

 

단점

- 등록한 관찰자를 삭제할 때 일련의 처리를 하지 않으면 불필요한 퍼포먼스 낭비가 일어날 수 있다.

 

- 옵저버들의 메소드 처리 순서에 따라 모호한 경우가 생길 수 있다.

 

- 명확하게 코드의 흐름을 파악할 수 있는 게 아니라, 런타임 때마다 디버그로 확인해야할 상황이 생길 수 있다.

 

더보기