한동안 비가 내려
날씨가 꽤 선선하였는데
오늘은 한 여름이었네요
피서의 계절이라
국내 여행지를 찾아보다가
가볼만한 유명지는
모두 꽉차있는 것을 보면
코로나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의
관계에 대응합니다
이것으로
이번 학습을 마치겠습니다
그럼 이만-_-
'Java' 카테고리의 다른 글
[Design Pattern] 상태 패턴(State Pattern) (0) | 2020.07.20 |
---|---|
[Design Pattern] 추억거리 패턴(Memento Pattern) (0) | 2020.07.16 |
[Design Pattern] 창구 패턴(Facade Pattern)과 중개자 패턴(Mediator Pattern) (0) | 2020.07.13 |
[Design Pattern] 책임 떠넘기기 패턴(Chain of Responsibility Pattern) (0) | 2020.07.12 |
[Design Pattern] 방문자 패턴(Visitor Pattern) (0) | 2020.07.09 |