옵저버 패턴이란,

Head First Design Patterns 의 내용을 빌어 말하자면

한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고

자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의한다.

다시 말하면 한 객체의 상태가 변경되면 그 객체에 의존하는 모든 객체에 연락이 간다!

라고 되어 있다.


계속 설명해 보자면 옵저버 패턴에 필요한 것에는 크게

주제, 옵저버
 
가 있다.

약간 생소하게 들릴수도 있는데(나도 확 와닿지 않는다) 더 자세히 설명하자면

주제에는 내용을 연락받을 객체들을 등록,삭제를 하거나 변경된 내용들을 알려주는

역할을 갖으며,

옵저버는 변경된 내용들을 전달하는 역할을 갖는다.

주제라는 말보단 관리자라는 말이 더 어울리지 않나 싶다.

간단한 내용들을 알았으니 코딩을 해보자.

앞의 스트래티지 패턴과 마찬가지로 트랜스포머를 예로 들어 설명하겠다.

물론 앞의 설명과 마찬가지로 실제 트랜스포머의 내용과 상당히 다를 수도 있다.

내가 구현할 내용들은 이렇다.

트랜스포머 본부 (주제 인터페이스)

트랜스포머 주유소 (주제 인터페이스를 구현한 주제 클래스)

트랜스포머 주유알림기 (옵저버 인터페이스)

트랜스포머 주유 디스플레이 (디스플레이 인터페이스)

옵티머스프라임(알림기, 디스플레이 인터페이스를 구현한)용 주유 디스플레이
(귀찮아서 범블비, 재즈용 주유 디스플레이는 안만들었다. ㅋㅋ)

이를 이용해 주유소에서 주유알림기를 통해 기름 주유를 알리면

주유알림기를 구현한 디스플레이들에게 자동적으로 주유 내용을 알려주게 된다.

이제 실제 코딩에 들어간다.

먼저 옵저버 인터페이스인 주유알림기를 만들어보자.

물론 주유알림기 외에도 다양한 옵저버를 만들어 사용할 수도 있다.

원하는 옵저버를 만들어 사용하면 된다.

주유알림기는 주유를 알려주는 oiling 메서드만 갖는다.

오토봇 디스플레이들은 주유알림기를 구현해야 일괄적으로 주유를 받을 수 있다.

이번엔 주제 인터페이스인 트랜스포머 본부를 만들어보자.

주유알림기를 구현한 오토로봇디스플레이들을 등록,삭제하는 메서드와

주유함을 알려주는 메서드가 구현되어있다.


본부를 만들었으면 본부를 구현한 주유소를 만들어보자.

주유소는 주유받을 오토봇디스플레이들을 등록, 삭제를 통해 통괄적으로 관리할 수 있고
 
주유여부를 통괄적으로 알려주는 역할을 한다.

하지만 주유소 클래스를 보면 오토봇디스플레이에 관한 정보는 전혀 없다는 것을 알 수 있다.

대신 오토봇디스플레이들이 주유알림옵저버를 구현받았기 때문에

주유소클래스에서는 주유알림옵저버 하나만 가지고도 주유알림옵저버를 구현한

오토봇디스플레이들을 직접적으로 관여하지 않고도 관리할 수 있다.

이렇게 하면 나중에 범블비나 재즈와 같은 다른 오토봇디스플레이를 추가시킬 때에도

주유소는 전혀 이 사실을 알 필요가 없으며 주유소에 대한 코드도 전혀 변경이 필요없다.

그냥 디스플레이만 추가하면 자동으로 주유를 할 수가 있는 것이다.

여기서 집고 넘어가는 디자인패턴-
서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는
디자인을 사용해야 한다!




이번에는 주유내용을 보여주는 디스플레이 인터페이스를 만들어 보자.



디스플레이 인터페이스를 구현하는 옵티머스프라임용 디스플레이를 만든다.
옵티머스프라임 디스플레이는
오일을 주유받기 위해 주유소를 매개변수로 가져와 주유소에 자기자신을 등록하고,
오일을 주유받고 주유받은 내용을 나타내기위해
주유알림기와 디스플레이를 구현받아 각 해당 메서드를 사용하고 있다.


이로써 필요한건 모두 만들어졌다.

이젠 한번 실행해보자.


아래는 실행 결과이다.

oil : 10
total oil : 10
oil : 20
total oil : 30
oil : 30
total oil : 60

주유가 아주 잘 되었음을 확인할 수 있다.

이제 옵티머스 프라임은 드라이브를 신나게 즐길 수 있다~


참고자료 : Head First Design Patterns
Posted by 윤연식
,