Observer 패턴
관찰 대상인 특정 객체의 상태가 변하면 그것을 관찰하는 다른 여러 객체에게 이 사실을 자동으로 통지하여 자동 갱신되도록 한다.
예시
엑셀에서 표를 이용하여 그래프를 생성했다고 하자
표의 값이 변경되면 그 즉시 그래프의 모양이 바뀌는것도 Observer패턴의 일부이다.
코드
다음은 Observer 패턴이 적용되지 않은 코드이다.
class Table {
private int a, b, c;
public void update(EData d) {
this.a = d.getA();
this.b = d.getB();
this.c = d.getC();
display();
}
public void display() {
}
}
class Bar {
private int a, b, c;
public void update(EData d) {
this.a = d.getA();
this.b = d.getB();
this.c = d.getC();
display();
}
public void display() {
}
}
class Circle{
private int a, b, c;
public void update(EData d) {
this.a = d.getA();
this.b = d.getB();
this.c = d.getC();
display();
}
public void display() {
}
}
EData에서 Table, Bar, Circle의 값이 변경되는 것을 관리하고, 변경된 값을 각 객체의 update 메소드를 이용하여 갱신한다.
class EData {
private Table table;
private Bar bar;
private Circle circle;
private int a, b, c;
public EData() {
table = new Table();
bar = new Bar();
circle = new Circle();
}
public void changed(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
table.update(this);
bar.update(this);
circle.update(this);
}
public int getA() {
return a;
}
public int getB() {
return b;
}
public int getC() {
return c;
}
}
class ETest {
public static void main(String[] args) {
EData eData = new EData();
eData.changed(10, 40, 50);
}
}
위 패턴에서 다른 그래프가 추가, 제거된다면 유지보수가 상당히 어려울 것이다.
따라서 Observer패턴을 적용하여 이를 해결하려한다.
interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
interface Observer {
public void update(Subject sub);
}
class EData implements Subject {
private List<Observer> observers;
private int a, b, c;
public EData() {
observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
if (!observers.isEmpty()) {
observers.remove(observers.indexOf(o));
}
}
@Override
public void notifyObservers() {
for (int i = 0; i < observers.size(); i++) {
Observer observer = observers.get(i);
observer.update(this);
}
}
public void changed(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
notifyObservers();
}
public int getA() {
return a;
}
public int getB() {
return b;
}
public int getC() {
return c;
}
}
class Table implements Observer {
private int a, b, c;
private Subject sub;
public Table(Subject sub) {
this.sub = sub;
sub.registerObserver(this);
}
public void update(Subject sub) {
if (sub instanceof EData) {
EData eSub = (EData) sub;
this.a = eSub.getA();
this.b = eSub.getB();
this.c = eSub.getC();
}
display();
}
public void display() {
}
}
결론
- 언제든지 새로운 observer를 추가하고 제거할 수 있다.
- Observer가 상태정보를 취하는 방법은 2가지가 있다.
- Push
- Observer가 필요한 상태 정보만을 가져오게 하는 방법
- Pull
- Subject에서 일방적으로 상태정보를 Observer에게 보내는 방법
- Push
[디자인 패턴] 개요
개요 설계 재사용에 의해 높은 생산성과 유지보수가 용시한 설계를 가능하도록 한다. 유사 객체들을 적절한 클래스로 추상화하고 인터페이스와 상속 관계를 포하한 주요 클래스 사이의 관계를
qpdh.tistory.com
'이론적인거 > 디자인 패턴' 카테고리의 다른 글
[디자인 패턴] Template Method 패턴 (0) | 2022.12.13 |
---|---|
[디자인 패턴] Adaptor 패턴 (0) | 2022.12.13 |
[디자인 패턴] Singleton 패턴 (0) | 2022.12.13 |
[디자인 패턴] 개요 (0) | 2022.12.13 |