본문 바로가기
개발/디자인 패턴

[Java 언어로 배우는 디자인 패턴 입문] 상태를 관리하기 17. Observer

by hongdor 2021. 1. 14.
728x90

출처 : 책 - java 언어로 배우는 디자인 패턴 입문

 

17. Observer - 중개인을 통해서 처리하기

 

 

1. 목적

 

 - MVC 패턴에서 Model과 View의 관계는 Subject(Model)과 Observer(View) 대응한다.

 - Mediator과 Observer 패턴은 비슷하지만,

   Mediator 패턴은 Colleague(Subject) 1개의 변화가 Mediator(Observer)를 통해 다수의 Colleague를 조정하기 위함이고

   Observer 패턴은 Subject 1개의 변화가 다수의 Observer에게 알려서 동기화를 이루는 것이 핵심이다.

 

 - Subject의 상태가 변화 - Observer 메소드 호출의 형태

 - Subject 클래스 속 Observer 인스턴스는 여러 종류 Observer 클래스들을 받기 위해서

   추상클래스 혹은 인터페이스로 선언한다.   

 - Observer는 관찰자 라는 의미지만 실제로는 전달받기를 기다리고 있다.

 - 주의 : Subject의 상태가 변화 - Observer 메소드 호출 - Subject의 상태가 변화 - Observer 메소드 호출-...

           이렇게 재귀가 일어나지 않도록 조심해야 한다.

 

 

2. 예제

 

(1) Observer - Observer 인터페이스

public interface Observer {
    public abstract void update(NumberGenerator generator);
}

 

 

(2) DigitObserver - Observer 구현1

public class DigitObserver implements Observer {
    public void update(NumberGenerator generator) {
        System.out.println("DigitObserver:" + generator.getNumber());
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
    }
}

 

 

(3) GraphObserver - Observer 구현2

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) {
        }
    }
}

 

 

(4) NumberGenerator - Subject1

import java.util.ArrayList;
import java.util.Iterator;

public abstract class NumberGenerator {
    private ArrayList observers = new ArrayList();     // Observer들을 저장
    public void addObserver(Observer observer) {    // Observer을 추가
        observers.add(observer);
    }
    public void deleteObserver(Observer observer) {  // Observer을 삭제
        observers.remove(observer);
    }
    public void notifyObservers() {                  // Observer에 통지
        Iterator it = observers.iterator();      
        while (it.hasNext()) {                 
            Observer o = (Observer)it.next();  
            o.update(this);                   
        }                                     
    }                                      
    public abstract int getNumber();                // 수를 취득한다
    public abstract void execute();                  // 수를 생성한다
}

 

 

(5) RandomNumberGenerator - Subject2

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();           
        }
    }
}

 

 

(6) Main

public class Main {
    public static void main(String[] args) {
        NumberGenerator generator = new RandomNumberGenerator();
        Observer observer1 = new DigitObserver();
        Observer observer2 = new GraphObserver();
        generator.addObserver(observer1);
        generator.addObserver(observer2);
        generator.execute();
    }
}

 

728x90

댓글