19.    The Observer Pattern

주가 정보의 변화 내역을 그래프와 테이블 또는 그래프와 리스트 박스의 형식으로 표현해야 할 경우가 있다.주가 정보가 변경될 때마다 수행해야 하는 추가적인 작업없이 이런 변경 내용을 한 번에 모든 출력물에 반영할 수 있게 되기를 원한다.

사용자 삽입 이미지

자바언에서는Observer패턴을 이용하여 이런 구현 목적에 맞게 프로그램을 쉽게 개발 할수 있다.

Observer패턴은 데이터를 포함하는 객체가 데이터의 내용을 출력하는 객체와는 분리되어 있으며,이러한 데이터 객체들은 데이터 안의 변화를 관찰한다는 전제하에서 사용된다.

그림음 이러한 내용을 도식화 한것이다.

Observer패턴을 구현할 때는 일반적으로 데이터를 주제로 그리고 각 출력 결과물을Observer요소로 언급한다.각각의Observer요소는 데이터에 자신의 관심 사항을 등록하는데,주제 요소의public메소드를 호출함으로써 등록 작업이 이루어지게 된다.각각Observer요소들은 데이터의 내용이 변경될 때 주제 요소가 호출하는 알려진 인터페이스를 갖는다.이런 인터페이스들은 다은과 같이 정의 할수 있다.

abstract interface Observer {

              //변경이 일어났는지를Observer에게 알린다.

              public void sendNotify (String s);

}

 

abstract interface Subject {

              //변경에 관심이 있다는 것을Subject에게 알린다.

              public void registerInterested (Observer obs);

}

이런abstract인터페이스를 정의함으로써 얻을 수 있는 장점은 개발자가 원하는 모든 종류의 클래스를 해당 클래스가 이런 인터페이스를 구현하는 한 얼마든지 만들어낼 수 있다는 것이다.또한 해당 요소들이 어떤 일을 수행하든지 객체들이 주제 요소 및Observer요소의 유형을 갖도록 선언할 수 있다는 것이다.

 

구조

사용자 삽입 이미지

 

역할

 

·         Subject: subject는 관련된observers를 알고있다.관련된 여러observer objectssubjectobserve하고 있다. subjectobserver objectsattachingdetaching하는interface을 제공한다.

·         Observer: observerupdating interface를 정의하며, subject가 변할 때update interface는 호출된다.

·         ConcreteSubject: ConcreteSubjectConcreteObserver Objects가 필요로 하는state를 저장하고 있다. ConcreteSubjectstate가 변할 때, ConcreteSubject는 관련된Observers에게 통보한다.

·         ConcreteObserver: ConcreteObserverConcreteSubject objectreference를 가지고 있다. ConcreteObserversubjectstateconsistency를 유지한다. ConcreteObserverupdating interface를 구현하여, subjectstateconsistency를 유지한다.

 

의도

하나의object상태가 변할 때,관련된object들이 자동으로notified and updated되기 위한object들간의one-to-many dependency을 정의한다.

 

적용시기

 

·         어떤abstraction이 두 개의 사물(aspects)과 하나의dependent을 가질 때이다.분리된objects내의 두 개의 사물(aspects)을 캡슐화 시키는 것은objects을 독립적이며 다양하게 재사용 할 수 있도록 한다.

·         하나의object가 변할 때 다른objects가 변화하여야 하며,얼마나 많은objects가 변화해야 하는지 모를 때이다.

·          

·         어떤object가 다른objects에게 통보할 때,어떤 기능을 하는지 알 필요가 없을 때이다.

 

결론

 

Observer들은Subject들에게 추상적인 커플링을 조장한다.어떤SubjectSubjectobserver들에 대해 자세히 알지 못한다.그러나 이것은 데이터를 변경시키는 것이 증가할 때Observer들을 연속적이거나 반복적으로 업데이트를 해야 하는 단점을 가질 수 있다.업데이트 비용이 높다면Observer들이 너무 자주 통보 받지 않도록 변경을 관리하는 어떤 정렬을 도입할 필요가 있다.

MediatorObserver

MediatorObserver패턴은 둘다상태 변화를 통진한다.’는 점은 닮아 있지만 목적이나 시점이 다르다.

l       Mediator패턴은 상태 변화가 통지되긴 하지만 그것은colleague역할을 조정하기 위한 목적으로 작동하고 있는mediator의 일부에 지나지 않는다.

l       Observer패턴에서는subject역할의 상태 변화를Observer역할에게 통지하는 것,통지를 해서 동기를 받아들이는 것이 핵심이다.

 

Observer인터페이스와Observable클래스

자바 언어는 다음과 같은 메소드를 갖는java.util.observer인터페이스를 갖는다.

 

public void update(Observable o, Object arg)

 

위의 메소드는 관찰 대상인 객체의 내용이 변경될 때마다 호출되도록 만들어진 메소드이다.이것은 두 번째 아규먼트가 해당 변경 사항의 성격을 기술하기 위해 사용될수 있다.

그러나 불행하게도 관찰 가능하다는 특성은 대부분 인터페이스보다는 클래스에서 구현된다.따라서 개발자는 해당 속성을 기본 클래스의 성격이 아직 규정되지 않았을 경우에만 사용할 수 있다.그러나 이런 경우는GUI어플리케이션에서는 거의 일어나지 않기 때문에Observable클래스는 거의 사용되지 않는다.반면 개발자는 이런Observer인터페이스를 쉽게 이용할 수 있다.

 

예제소스

사용자 삽입 이미지

 

예제 소스

public interface Observer {

   public abstract void update(NumberGenerator generator);

}

 

public class DigitObserver implements Observer {

 

   public void update(NumberGenerator generator) {

       System.out.println("DigitObserver:" + generator.getNumber());

       try {

           Thread.sleep(100);

       } catch (InterruptedException e) {

       }

   }

}

 

public class GraphObserver implements Observer {

 

   public void update(NumberGenerator generator) {

       System.out.print("GraphObserver:");

       int count = generator.getNumber();

       for (int i = 0; i < count; i++) {

           System.out.print("*");

       }

       System.out.println("");

       try {

           Thread.sleep(100);

       } catch (InterruptedException e) {

       }

   }

}

 

import java.util.Vector;

import java.util.Iterator;

 

public abstract class NumberGenerator {

   private Vector observers = new Vector();

   

   public void addObserver(Observer observer) {

       observers.add(observer);

   }

   

   public void deleteObserver(Observer observer) {

       observers.remove(observer);

   }

   

   public void notifyObservers() {

       Iterator it = observers.iterator();

       while (it.hasNext()) {

           Observer o = (Observer)it.next();

           o.update(this);

       }

   }

   

   public abstract int getNumber();

   public abstract void execute();

}

 

import java.util.Random;

 

public class RandomNumberGenerator extends NumberGenerator {

   private Random random = new Random();

   private int number;

   

   public int getNumber() {

       return number;

   }

   

   public void execute() {

       for (int i = 0; i < 20; i++) {

           number = random.nextInt(50);

           notifyObservers();

       }

   }

}

 

public class mainClass {

   public static void main(String[] args) {

       mainClass client = new mainClass();

       client.exec();

   }

 

   public void exec() {

       NumberGenerator generator = new RandomNumberGenerator();

       Observer observer1 = new DigitObserver();

       Observer observer2 = new GraphObserver();

       generator.addObserver(observer1);

       generator.addObserver(observer2);

       generator.execute();

   }

}

 

관련패턴

l       Mediator pattern : Mediator패턴에서는MediatorColleague역할이 통신할 때Observer패턴을 사용하는 경우가 있다.

'Programming > Design Pattern' 카테고리의 다른 글

[펌] The View Helper Pattern  (0) 2006.01.21
[펌] The Composite View pattern  (0) 2006.01.21
[펌] The Observer Pattern  (0) 2006.01.21
[펌] The State Pattern  (0) 2006.01.21
[펌] The Template Pattern  (0) 2006.01.21

Posted by 영웅기삼
,