먼저 이 글은 영문 위키의 글을 번역한 글임을 알려드립니다.
영어 실력이 부족한 관계로 오역이 있을 수도 있습니다.
원문 주소 : http://en.wikipedia.org/wiki/Observer_pattern
Behavioral - Observer pattern
옵저버(observer) 패턴은 subject라 불리는 객체(object)가 observer라 불리는 객체들의 리스트를 관리하고, 상태변화가 있으면 알아서 옵저버 객체들에게 알려주는(종종 옵저버의 메서드 methods를 호출함으로써 알려주는) 디자인 패턴(software design pattern)이다.
이 패턴은 주로 분산된 이벤트 처리(event handling) 시스템에서 사용된다. 또한 옵저버는 MVC 패턴의 중요한 부분이기도 하다.
사실, 옵저버는 Smalltalk의 MVC 기반 UI 프레임웍에서 가장 먼저 구현되었다.
관련된 패턴들 : Publish-subscribe pattern, mediator, singleton
구조 Structure
정의 Definition
옵저버 패턴의 정수(essence)는 다음과 같다.
객체 사이에 일대다(one-to-many) 관계를 정의함으로써, 한 객체의 상태가 변경되었을 때 의존하는(dependents) 객체들에게 자동으로 알려주고 업데이트하도록 하기 위함이다.
예 Example
아래는 키보드 입력을 받아서 한줄 마다 이벤트로 처리하는 예이다. 이 예는 java.util.Observer 와 java.util.Observable 이 두개의 라이브러리 클래스를 사용해서 만들었다. System.in 으로부터 문자열이 들어오면 notifyObservers()메서드가 호출되고, 그러면 모든 옵저버들의 update메서드를 호출함으로써(이 예에서는 ResponseHandler.update메서드) 이벤트의 발생을 알린다.
MyApp.java파일에 코드를 실행시킬 수 있는 main()메서드가 있다.
/* File Name : EventSource.java */ package org.wikipedia.obs; import java.util.Observable; //Observable is here import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class EventSource extends Observable implements Runnable { public void run() { try { final InputStreamReader isr = new InputStreamReader(System.in); final BufferedReader br = new BufferedReader(isr); while (true) { String response = br.readLine(); setChanged(); notifyObservers(response); } } catch (IOException e) { e.printStackTrace(); } } }
/* File Name: ResponseHandler.java */ package org.wikipedia.obs; import java.util.Observable; import java.util.Observer; /* this is Event Handler */ public class ResponseHandler implements Observer { private String resp; public void update(Observable obj, Object arg) { if (arg instanceof String) { resp = (String) arg; System.out.println("\nReceived Response: " + resp ); } } }
/* Filename : MyApp.java */ /* This is the main program */ package org.wikipedia.obs; public class MyApp { public static void main(String[] args) { System.out.println("Enter Text >"); // create an event source - reads from stdin final EventSource eventSource = new EventSource(); // create an observer final ResponseHandler responseHandler = new ResponseHandler(); // subscribe the observer to the event source eventSource.addObserver(responseHandler); // starts the event thread Thread thread = new Thread(eventSource); thread.start(); } }
구현 Implements
옵저버 패턴은 거의 대부분의 GUI 툴킷을 포함한 많은 프로그래밍 라이브러리(programming libraries)와 시스템에서 구현되어 있다. 아래와 같은 주목할만한 구현들이 있다.
ActionScript
- ActionScript3.0에 있는 flash.events 패키지 (ActionScript 2.0에서 mx.events 패키지였다.)
C
C++
- libsigc++ - C++ signalling 템플릿 라이브러리
- sigslot - C++ Signal/Slot 라이브러리
- Cpp::Events - 템플릿 기반의 C++ 구현(이벤트 객체의 관리 인터페이스를 호출 인터페이스로부터 분리했다.)
- XLObject - 템플릿 기반의 C++ signal/slot 모델
- Signals - 가볍고 non-intrusive한 C++ signal/slot 모델 구현
- libevent - 멀티 쓰레드 크로스 플랫폼 signal/slot C++ 라이브러리
- Boost.Signals - signal/slot 모델의 구현
- MFC의 CDocument - CView - 프레임워크
- Qt C++ 프레임워크의 signal/slot 모델
- Advanced Component Framework의 컴포넌트 기반 Model/Observer 패턴 구현
- MRPT 로보틱스 C++ 프레임워크의 observer/observable 모델
Objective-C
C#
- IObserver<T> 인터페이스 - .NET 프레임웍 4 이상에서 지원되는 옵저버 패턴의 구현
- Exploring the Observer Design Pattern - 위임(delegates)과 Event패턴을 사용한 C#과 Visual Basic .NET 구현
ColdFusion
- http://www.cfdesignpatterns.com/behavioral-patterns/observer-design-pattern-in-coldfusion/
- http://coldfusioneventmanager.riaforge.org/
Delphi
Java
- java.util.Observer 클래스에서 간단한 옵저버 구현을 제공하고 있다.
- 전형적으로 자바에서 이벤트는 callback 패턴으로 구현되어 있다. : 한 부분은 공통 인터페이스를 제공하고, 다른 부분은 그 인터페이스를 구현하고, 또 다른 부분은 인터페이스에 대한 레퍼런스를 가지고 있다가 이벤트를 발생시킨다.
JavaScript
- EventDispatcher singleton
- DevShop
- jQuery에서 이벤트 핸들러를 만들기 위해 '.on()'을 쓰고, 이벤트를 발생시키기 위해 '.trigger()'를 쓰고, 이벤트 핸들러를 제거하기 위해'off()'를 사용하도록 되어 있는데, 이 것이 옵저버 패턴을 구현한 부분이다. jQuery에서는 실제 메모리에 DOM 요소를 올려서 사용하는데, 이벤트 핸들러는 DOM구조에 붙였다가 DOM의 해당 요소가 삭제되면 자동적으로 이벤트도 삭제된다. 더 많이 알고 싶다면 jQuery Event Model 슬라이드 쇼를 봐라.
Lisp
Perl
- Class::Observable 기본 옵저버 패턴 구현
- Class::Publisher 약간 더 발전된 구현
- POE::Component::Syndicator - POE를 위한 옵저버 패턴
PHP
- Symfony2 Event Dispatcher - Symfony 팀이 만든 라이브러리 컴포넌트
- Event_Dispatcher
- SPLSubject 와 SPLObserver - 표준 PHP 라이브러리의 일부
- prggmr - PHP 5.4이상에서 가볍고 빠르고 아주 간단하게 사용할 수 있도록 설계한 이벤트 처리 엔진
Python
- Louie - Patrick K. O'Brien이 구현
- PyDispatcher - Django 웹 프레임웍의 signal이 기반으로하고 있는 구현
- Py-notify
- Observer Pattern using Weak References - Michael Kent가 구현
- PyPubSub
- NotificationFramework
- Blinker
- Jpblib
Ruby
Other/Misc
'Design Patterns > 영문 위키(Wikipedia)' 카테고리의 다른 글
Strategy pattern (0) | 2012.07.04 |
---|---|
State pattern (0) | 2012.07.03 |
Memento pattern (0) | 2012.06.20 |
Mediator pattern (0) | 2012.06.19 |
Iterator pattern (0) | 2012.06.18 |