본문 바로가기

Design Patterns/영문 위키(Wikipedia)

Observer pattern

먼저 이 글은 영문 위키의 글을 번역한 글임을 알려드립니다.

영어 실력이 부족한 관계로 오역이 있을 수도 있습니다.

원문 주소 : 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.Observerjava.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


C


C++


Objective-C


C#


ColdFusion


Delphi


Java

  • java.util.Observer 클래스에서 간단한 옵저버 구현을 제공하고 있다.
  • 전형적으로 자바에서 이벤트는 callback 패턴으로 구현되어 있다. : 한 부분은 공통 인터페이스를 제공하고, 다른 부분은 그 인터페이스를 구현하고, 또 다른 부분은 인터페이스에 대한 레퍼런스를 가지고 있다가 이벤트를 발생시킨다. 


JavaScript

  • EventDispatcher singleton
  • DevShop
  • jQuery에서 이벤트 핸들러를 만들기 위해 '.on()'을 쓰고, 이벤트를 발생시키기 위해 '.trigger()'를 쓰고, 이벤트 핸들러를 제거하기 위해'off()'를 사용하도록 되어 있는데, 이 것이 옵저버 패턴을 구현한 부분이다. jQuery에서는 실제 메모리에 DOM 요소를 올려서 사용하는데, 이벤트 핸들러는 DOM구조에 붙였다가 DOM의 해당 요소가 삭제되면 자동적으로 이벤트도 삭제된다. 더 많이 알고 싶다면 jQuery Event Model 슬라이드 쇼를 봐라.


Lisp


Perl


PHP


Python


Ruby

  • Observer - 루비 표준 라이브러리에 있다.

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