그냥 하는 노트와 메모장

옵저버 패턴(Observer pattern) 본문

GoF design pattern

옵저버 패턴(Observer pattern)

coloredrabbit 2019. 3. 9. 14:31

* 옵저버 패턴(Observer pattern)

[정의] 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 방식으로 의존성을 정의한다.





[그림 : UML(출처: https://en.wikipedia.org/wiki/Observer_pattern)]



  옵저버 패턴은 크게 주제(Subject) 클래스와 옵저버(Observer) 클래스로 이루어져 있다. 주제 클래스는 감시 가능한 데이터를 가지고 있고, 이 데이터들을 보고 싶은 클래스를 옵저버 클래스로 둔다.

  옵저버 패턴의 핵심은 감시 가능한 데이터의 변경에 대해 "알람"을 받고 싶은 클래스들이 많을 때 활용할 수 있다. 아날로그적으로 비유하자면 신문 배달이나 방송으로 둘 수 있다. 신문을 예시로 더 깊게 들어가보면 신문은 구독을 신청한 사람에게만 전달된다. 신문 배달부는 어디에 배달해야 하는지 "주소"만 알고 있으며 그 주소에 살고 있는 "사람"이 누구인지, 뭘 하는 사람인지 알지도 알 필요도 없다.





[ 그림 : 신문 배달부(출처: https://kr.freeimages.com/premium/paperboy-delivering-the-newspaper-1810864)]


  옵저버 패턴은 이 신문 배달처럼 똑같은 방식을 보여준다. 신문사가 곧 주제 클래스, 신문은 감시 가능한 데이터, 구독자는 옵저버 클래스가 되며 주소는 그대로 옵저버 클래스의 객체의 레퍼런스가 된다. 또한 구독자의 정보를 주소말고 알 필요가 없다는 점은 느슨한 결합(Loose coupling) 개념에 부합한다.

  ※ 느슨한 결합(Loose coupling)은 서로 다른 두 객체가 서로에 대해 상호작용은 하지만 서로에 대해 잘 모른다는 것을 의미한다. 상호작용에 필요한 메소드만을 사용하겠다는 것이다.



[ 표 : 신문과 옵저버의 유사성 ]



  주제 클래스는 자신의 데이터를 관찰하고자 하는 옵저버 클래스 컬렉션(Collection)을 가지고 있으며 옵저버 추가 및 제거가 가능하다. 이는 곧 UML에서 주제 클래스와 옵저버 클래스의 집합 관계(Aggregation, 비어있는 다이아)로 확인할 수 있다.



* 알림 방식(Notify methods)

  주제 클래스에서 등록된 옵저버들에게 데이터가 변경됐음을 알릴 때 사용할 수 있는 방식은 두 가지가 있다. 두 가지 모두 사용할 수 있으며 장단점을 잘 보며 선택하자


  1. Push 방식 - 인자(Parameter) 사용

     데이터를 넘겨주는 방식이 주제 클래스에서 직접 넘겨주는 방식이다.

     - 장점: 단 번에 데이터들을 인자로 넘겨줌으로써 모든 옵저버들에게 같은 방식으로 알려줄 수 있다.

     - 단점: 멤버 변수가 추가되면 옵저버의 인터페이스는 물론, 모든 옵저버 클래스의 소스를 수정해야 한다.

       ※ 넘겨주는 인자를 클래스로 두어서 그 클래스 안에서 처리한다면 해결할 수 있긴하다.

     ex) void update(MyDataClass myDataClass); // MyDataClass에 데이터를 추가 및 삭제


  2. Pull 방식 - getter/ setter 메소드 사용

     데이터를 얻어오는 방식이 옵저버 클래스에서 주제 클래스의 getter/ setter 메소드를 통해 가져오는 방식이다.

     - 장점: 각 옵저버 클래스에서 필요한 데이터만 가져올 수 있다.

     - 단점: 주제 클래스에 대한 캡슐화가 깨질 수 있다. 또한 느슨한 결합으로 볼 수 없을 수 있다.

'GoF design pattern' 카테고리의 다른 글

프록시 패턴(Proxy pattern)  (0) 2019.03.09
Comments