Design Pattern 중 이번 시간은 Observer Pattern 에 대해서 알아보겠습니다.
Observer란 이름은 많이 친숙하시지 않으신가요? 한 번쯤 스타크래프트 란 게임에서 보이지 않은 상태에서 탐색을 위한 비행체로 나오는데요. Observer Pattern은 무엇일까요??
Observer는 관찰자, 관측자, 목격자 등의 뜻을 가지고 있는데요. Observer들도 마찬가지 입니다.
주제 객체를 바라보고 있는 놈들이죠. Observer Pattern은 크게 주제 객체와 옵저버 객체로 나눠져 있습니다. 그럼 한번 제대로 알아보죠.
Observer Pattern의 개요는 아래와 같습니다.
" 객체들에게 연락망을 돌립시다 "
Head First Design Pattern에서는 Observer 패턴을 출판사+구독자로 표현하였는데요, 잘 생각하면
맞는 소리입니다. 출판사를 주제(subject), 구독자를 옵저버(observer)라고 부른다는 것을 아시면 편합니다. 구독자들은 출판사에 잡지를 받겠다고 등록을 하고 주제에 등록합니다. 그 후에 주제 객체는 구독자들에게 소식을 전달하는 것입니다. 그리고 여러분들이 잡지 구독을 해지하게 되면 옵저버에서 빠져나오고 잡지(소식)을 전달 받지 못하는 것 입니다.
일단 기본적인 개요는 위의 내용과 같습니다. 그럼 아래 그림을 보시면 위의 내용이 더 이해가 잘 되실려나 모르겠습니다. 제가 글로 표현하는 걸 잘 하는 게 아니라서 말이죠 ;; 한번 보시죠.
하나의 Subject(주제)를 다양한 Observer들이 구독하고 있는 방식입니다. One Source Multiple Use라는 말이 딱 맞는다고 생각되는데요,
Observer Pattern의 정의는 아래와 같습니다.
한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many)의존성을 정의합니다.
자 여기서 한가지 궁금증이 생깁니다.
어떻게 Subject가 다른 Observer들에게 상태의 변화를 전달할까??
참 어렵습니다. Observer Pattern이 무엇인지에 대해서는 감은 잡혔지만, 정확히 어떻게 설계를 하고 구현을 해야 할지 알기 힘듭니다. 하나하나 알아봅시다.
Observer Pattern의 기본적인 구조에 대해 먼저 살펴봅시다.
별도의 주제 객체에 관심이 있는 부양가족(Observer)의 리스트를 유지하기 위해 Observer 패턴을 사용합니다. 모든 Observer와 종속 객체 사이의 직접 종속성을 제거하는 일반적인 Observer Interface를 구현해야 합니다.
주제를 나타내는 Subject객체에서는 옵저버로 등록하거나 옵저버 목록에서 탈퇴하고 싶을때 이 객체의 메소드를 사용합니다. 그리고 각 주제마다 여러개의 옵저버가 있습니다. 옵저버가 되는 객체는 반드시 Observer 인터페이스를 구현해야 합니다. 그리하여 특정 주제 객체의 옵저버 클래스가 되어 정보를 받을 수 있습니다. ConcreateSubject는 주제 역할을 하는 구상 클래스 입니다. 주제 클래스에서는 등록 및 해지를 위한 메소드 외에 상태가 바뀔때마다 모든 옵저버들에게 연락을 하기위한 Notify 메소드가 구현되어 있습니다.
Observer Pattern은 두가지 모델로 설명할 수 있습니다.
내용의 변경을 알리는 방식을 두가지로 설명할 수 있습니다. Push Model와 poll Model입니다.
|
Push Model |
Poll Model |
내용 |
Subject는 데이터가 변경될 때 마다 Observer들에게 알림 |
Observer가 갱신된 데이터가 필요할 때 마다 Getter 메소드를 이용하여 Subject로 부터 데이터 가져옴 |
장점 |
Observer는 Subject에게 따로 데이터를 요청할 필요 없음. |
Observer는 필요한 데이터만 가져 올 수 있다. Subject가 확장되더라도 Subject는 notify메소드를 수정할 필요 없이 Getter메소드 만 추가하면 된다. |
단점 |
Observer가 불필요한 데이터까지 받아야 되는 경우 발생. |
Observer는 필요한 데이터가 많을 수록 Getter메소드 여러 번 호출 해야 한다. |
위의 설명과 같이 두가지 방식으로 설명 할 수 있습니다.
어떤 식으로 진행되는 지 아래 두가지 모델을 한번 비교해 보도록 하죠.
Push Model은 Subject가 Observer들에게 알림을 하는 방식인데요, 각 객체들이 Observer로 등록 요청을 하고 알림을 Observer들에게 update하는 방식으로 진행됩니다.
Pull Model은 Domain Object에서 알림을 발생시키면 Subject에서 update를 알리고 각 Observer들은 getter를 이용하여 알림을 받는다. Pull Model을 보면 위에 보시던 Observer 구조와 다름을 알 수 있는데요, 이 부분에 대해서는 다음에 설명드릴게요 ^^. 이번 시간에는 이런 것이 있다 라는 정도로만 알고 넘어 가시면 될 것 같습니다.
Observer Pattern에서의 디자인 원칙을 한번 살펴 볼까요?
1. 어플리케이션에서 바뀌는 부분을 찾아내서 바뀌지 않는 부분으로부터 분리시킨다.
-> 변하는 것 : 주제의 상태, 옵저버의 개수, 옵저버의 형식
2. 특정 구현이 아닌, 인터페이스에 맞춰서 프로그래밍 한다.
-> Subject와 Observer를 모두 인터페이스를 사용해서 관리. (Losses Coupling)
3. 상속보다는 구성을 활용한다.
-> 구성을 활용하여 Observer들을 관리합니다.
마지막으로 Observer Pattern 사용시 주의할 점을 말씀드리겠습니다.
위의 그림을 보시면 됩니다. 꼭 옵저버로 등록된 순서대로 알림을 할려고 하실 필요도 없으시구요.
옵저버에서 알림 후 거기서 무한루프에 빠지는 경우가 종종 있는데요. 그러한 경우만 주의하시면 될 것 같습니다 ^^
Observer Pattern 의 구현 예시 코드는 검색하시면 정말 많이 찾으실 수 있으실 겁니다.
그래서 따로 설명은 드리지 않고, Observer Pattern에 대한 설명을 마치도록 하겠습니다.
※함께 스터디 중인 김민수, 은희유 님 감사.
'Software Architecture > Design Pattern' 카테고리의 다른 글
[Design Pattern] Iterator Pattern (0) | 2018.12.18 |
---|---|
[Design Pattern] Template Method Pattern (0) | 2018.12.15 |
[Design Pattern] Null Object Pattern (0) | 2017.02.20 |
[Design Pattern] Strategy pattern (0) | 2014.07.15 |
[Design Pattern] Design Pattern 이란? (0) | 2014.07.06 |