티스토리 뷰
1. 옵저버 패턴이란?
한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 1:N 의존성을 정의한다.
구성요소
1. Subject
- Observer 목록을 가지고 있다. Observer의 수에는 제한이 없음.
- Observer를 추가/제거 하는 인터페이스 제공
2. Observer
- 업데이트 인터페이스를 제공. (이 업데이트 인터페이스는 해당되는 Subject에 변화가 있을 때 갱신하는 것을 의미)
3. ConcreteSubject
- ConcreteObserver 객체들이 필요로 하는 정보를 가지고 있다.
- 상태가 변하면 가지고 있는 ConcreteObserver들에게 공지함.
4. ConcreteObserver
- ConcreteSubject 객체에 대해 참조
- 해당되는 Subject와 동기화 되는 상태를 가지고 있다.
- Observer의 업데이트 인터페이스를 구현함.
기본이 되는 디자인 원칙
Loose Coupling: 서로 상호작용을 하지만 서로에 대해 잘 모르는 것을 의미
- Subject가 Observer에 대해 아는 것은 Observer가 특정 인터페이스를 구현한다는 것 뿐이다.
- Observer는 언제든지 새로 추가/제거
- 새로운 형식의 Observer를 추가하려고 할 때 Subject에 변경 필요 없음
- Subject / Observer는 서로 독립적으로 재사용 가능
- Subject / Observer가 바뀌더라도 서로 영향 없음
2. 동기
객체의 변화가 synchronize 되야하거나 broadcast의 성격을 띌 때 사용할 수 있다.
장점:
- 상태를 변경하는 객체(publisher)와 변경을 감지하는 객체(subscriber) 관계를 느슨하게 유지
- subject의 상태 변경을 주기적으로 조회하지 않고 자동으로 감지
- 런타임에 옵저버를 추가/제거
단점:
- 복잡도 증가
- 다수의 Observer 객체를 등록 이후 해지하지 않으면 memory leak
-> 해지하는게 가장 좋지만 Weak Reference도 참고
- 원치않은 notification
- 서로에 대한 정보가 없다보니 update 비용을 모른다
3. 예제
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers(); // subject 객체의 상태 변경 시 모든 객체들에게 공지
}
public interface Observer {
public void update(Object state);
}
public interface DisplayObject {
public void display();
}
public class ConcreteSubject implements Subject {
private ArrayList observers;
private Object state;
public ConcreteSubject() {
observers = new ArrayList();
}
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if ( i > = 0) {
observers.remove(i);
}
}
public void notifyObservers() {
for (Observer o : observers) {
o.update(state);
}
}
public void stateChanged() {
notifyObservers();
}
public void setState(Object newState) {
this.state = newState;
stateChanged();
}
}
public class ConcreteObserver implements Observer, DisplayObject {
private Subject subject;
private Object state;
public ConcreteObserver(Subject subject) {
this.subject = subject;
subject.registerObserver(this);
}
public void update(Object state) {
this.state = state;
display();
}
public void display() {
System.out.println("Current State:" + state.toString());
}
}
Java에서의 옵저버 패턴
-> java8 이후의 대안 (Flow API)
-> Spring에서는 ApplicationRunner, ApplicationEventPublisher, ApplicationContext 사용
개인적인 포인트
- 두 객체간 의존성이 포착되고 그게 추상적으로 일방향적이어야 된다는 느낌이 들 때 떠올려볼만한 패턴인 것 같다.
- 특히 그 일방향성을 가진 의존성이 1:N이면 딱 맞는 상황
- 잘 안쓸거 같다. 내가 직접 사용하기 보다 프레임워크를 사용하면서 이 패턴이 적용된 거는 볼 수 있지 않을까 (자바 스윙이라던지..)
'Computer Science > 디자인 패턴' 카테고리의 다른 글
5. 싱글턴 패턴 (Singleton Pattern) (0) | 2023.09.10 |
---|---|
4-2. 추상 팩토리 패턴 (Abstract Factory Pattern) (0) | 2023.09.01 |
4-1. 팩토리 메서드 패턴 (Factory Method Pattern) (0) | 2023.09.01 |
3. 데코레이터 패턴 (Decorator Pattern) (1) | 2023.08.29 |
1. 스트래티지 패턴 (Strategy Pattern) (0) | 2023.08.11 |
- Total
- Today
- Yesterday
- Spring
- 2020 KAKAO
- nginx 내부
- Kakao Blind
- Java #JIT #JVM
- Java #GC #가비지콜렉터 #Garbage Collector
- 스프링
- 카카오
- decorator
- 2021
- KAKAO 2021
- 카카오 인턴
- 카카오코테
- PatternSyntaxException
- spring cloud sleuth
- behavior parameterization
- 카카오 코테
- 신규 아이디 추천
- jvm
- Java
- 코테
- WORA
- okhttp3
- WORE
- 디자인패턴
- 2019 Kakao Blind
- 프로그래밍 모델
- 모던 자바 인 액션
- zipkin
- IOC
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |