Java

[Design Pattern] 관찰자 패턴(Observer Pattern)

구루싸 2020. 7. 15. 21:47
반응형
SMALL

한동안 비가 내려

날씨가 꽤 선선하였는데

오늘은 한 여름이었네요

피서의 계절이라

국내 여행지를 찾아보다가

가볼만한 유명지는

모두 꽉차있는 것을 보면

코로나19도

한 여름의 피서를

막지 못하나 봅니다

무튼 이번 학습 주제는

관찰자(Observer) 패턴입니다

스타크래프트 좀 하신 분들은

아주 익숙한 단어 Observer!

스타에서 옵저버가 하는 일은

맵을 밝혀서 우리에게

적의 위치를 알려주는데

이 패턴도 비슷하게

관찰 대상의 상태가 변화하면

관찰자에게 알려줍니다

이번에도 관찰자 패턴의

역할들을 정리하고 시작하겠습니다

역할 설명
Subject(관찰 대상자) 관찰이 되는 대상으로 Observer 역할을 등록, 삭제하는 메소드를 가짐
Concrete Subject(구체적인 관찰자) 구체적으로 관찰되는 대상으로 상태 변화를 Observer 역할에 전달
Observer(관찰자) Subject 역할로부터 상태 변화를 전달 받는 역할
Concrete Observer(구체적인 관찰자) 구체적인 관찰자

이번 역할들은

관찰자와 관찰 대상자

두가지네요^^

그럼 구현을 해보겠습니다

1. 인터페이스(Interface) Observer.java

package observerPattern;

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

2. 클래스(Class) DigitObserver.java

package observerPattern;

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

3. 클래스(Class) GraphObserver.java

package observerPattern;

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 ) {
			/* Ignore */
		}
	}
}

4. 추상 클래스(Abstract Class) NumberGenerator.java

package observerPattern;
import java.util.*;
public abstract class NumberGenerator {
	private ArrayList<Observer> observers = new ArrayList<Observer>();
	public void addObserver(Observer observer) {
		observers.add(observer);
	}
	public void deleteObserver(Observer observer) {
		observers.remove(observer);
	}
	public void notifyObservers() {
		Iterator<Observer> it = observers.iterator();
		while(it.hasNext()) {
			Observer o = (Observer)it.next();
			o.update(this);
		}
	}
	public abstract int getNumber();
	public abstract void execute();
}

5. 클래스(Class) RandomNumberGenerator.java

package observerPattern;
import java.util.*;
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. 클래스(Class) Test.java

import observerPattern.*;
public class Test {
	public static void main(String[] args) {
		/* Observer Pattern */
		NumberGenerator generator = new RandomNumberGenerator();
		Observer digit = new DigitObserver();
		Observer graph = new GraphObserver();
		generator.addObserver(digit);
		generator.addObserver(graph);
		generator.execute();
	}
}

위의 코드에서는

일어나지 않지만

이번 패턴에서 주의할 점은

Observer의 행위가

Subject에 영향을 미칠 때인데

(Subject의 상태가 변화)

이런 경우에 무한 루프가

발생할 수 있기 때문입니다

또 관찰자는 능동적으로

관찰하지 않고

수동적으로 전달받기를

기다리고 있습니다

이 때문에 관찰자 패턴은

Publish-Subscribe 패턴으로

부르기도 합니다

우리가 많이 들어본

MVC(Model/View/Controller) 모델의

Model과 View의 관계는

이 패턴의 Subject와 Observer의

관계에 대응합니다

이것으로

이번 학습을 마치겠습니다

그럼 이만-_-

 

반응형
LIST