일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- Design Patterns
- tool
- java
- elasticsearch
- jsp
- it
- 맛집
- jenkins
- Git
- db
- Spring
- AWS
- JVM
- ReactJS
- Web Server
- MySQL
- devops
- Spring Batch
- redis
- IntelliJ
- ubuntu
- php
- Oracle
- laravel
- javascript
- linux
- Spring Boot
- springboot
- Gradle
- 요리
Archives
- Today
- Total
아무거나
[Design Pattern] Observer Pattern 본문
반응형
옵저버 패턴(Observer Pattern)
옵저버 패턴을 통하여 이벤트 발생
후 객체 외부
에서 처리 할 수 있다.
Target 객체가 Observer 인터페이스를 가지고 있어서 notify()에서 update()를 호출해서 해당 Observer나 Target 객체에 상태변경(이벤트처리된것을 확인하는 패턴
옵저버 패턴 예시 - 1
가장 기본적인 옵저버 패턴을 구현하자
Button 클래스를 생성한다.
[Button.java]
package com.bkjeon.observer;
public class Button {
// notify
public void onClick() {
if (onClickListener != null) {
onClickListener.onClick(this);
}
}
// Observer Interfacse
public interface OnClickListener {
public void onClick(Button button);
}
private OnClickListener onClickListener;
// setObserver
public void setClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
}
메인 클래스를 작성하자.
[Main.java]
package com.bkjeon.observer;
public class Main {
public static void main(String[] args) {
Button button = new Button();
button.setClickListener(new Button.OnClickListener() {
@Override
public void onClick(Button button) {
System.out.println(button + "is Clicked");
}
});
button.onClick();
}
}
실행결과
...Button@27d6c5e0is Clicked
옵저버 패턴 예시 - 2
자바에서 기본적으로 옵저버 패턴을 구현할 때 제공하는 클래스와 인터페이스를 이용해서 구현하자.
해당 API는 Java9 버전부터 Deprecated가 되었으므로 참고만 하자. (https://docs.oracle.com/javase/9/docs/api/java/util/Observable.html)
- Observer: update함수가 있는데 여기서 받는 매개변수는 어떤것이 업데이트 되었는지(=Observable) 그리고 변경사항 혹은 어떤 이벤트인지(=Observer)를 매개변수로 받고 있다.
- Observable: Observer 할 수 있는 클래스를 구현가능하게 해주는 클래스
먼저 Observable를 상속받은 Button 클래스를 구현하자
[Button.java]
package com.bkjeon.observer.example2;
import java.util.Observable;
public class Button extends Observable {
public void onClick() {
setChanged();
notifyObservers();
}
}
메인 클래스를 작성하자.
[Main.java]
package com.bkjeon.observer.example2;
import java.util.Observable;
import java.util.Observer;
public class Main {
public static void main(String[] args) {
Button button = new Button();
button.addObserver(new Observer() {
@Override
public void update(Observable observable, Object o) {
System.out.println(observable + " is Clicked");
}
});
button.onClick();
button.onClick();
button.onClick();
}
}
옵저버 패턴 예시 - 3
아래 목록을 사용하여 더 실용적으로 구현
- 제네릭
- 델리게이트
- 내부에 옵저버를 넣는다.
먼저 클래스 내부의 멤버변수로 사용할 Observable 클래스를 구현하자.
[Observable.java]
package com.bkjeon.observer.example3;
import java.util.Vector;
public class Observable<T> {
private boolean changed = false;
private Vector<Observer<T>> obs = new Vector();
public Observable() {
}
public synchronized void addObserver(Observer<T> o) {
if (o == null) {
throw new NullPointerException();
} else {
if (!this.obs.contains(o)) {
this.obs.addElement(o);
}
}
}
public synchronized void deleteObserver(Observer<T> o) {
this.obs.removeElement(o);
}
public void notifyObservers() {
this.notifyObservers(null);
}
public void notifyObservers(T arg) {
Vector<Observer<T>> arrLocal;
synchronized(this) {
if (!changed) {
return;
}
arrLocal = (Vector<Observer<T>>) obs.clone();
clearChanged();
}
for (Observer<T> observer: arrLocal) {
observer.update(this, arg);
}
}
public synchronized void deleteObservers() {
this.obs.removeAllElements();
}
public synchronized void setChanged() {
this.changed = true;
}
protected synchronized void clearChanged() {
this.changed = false;
}
public synchronized boolean hasChanged() {
return this.changed;
}
public synchronized int countObservers() {
return this.obs.size();
}
public interface Observer<T> {
void update(Observable<T> o, T org);
}
}
그 다음 Button을 구현하고 델리게이트를 사용해보자.
[Button.java]
package com.bkjeon.observer.example3;
import com.bkjeon.observer.example3.Observable.Observer;
public class Button {
public Button() {
observable = new Observable<String>();
}
private Observable<String> observable;
public void addObserver(Observer<String> o) {
observable.addObserver(o);
}
public void notifyObservers() {
observable.notifyObservers(null);
}
public void onClick() {
observable.setChanged(); // 중요(변경되었다는걸 알림)
notifyObservers();
}
}
메인 클래스를 구현하자.
[Main.java]
package com.bkjeon.observer.example3;
public class Main {
public static void main(String[] args) {
Button button = new Button();
button.addObserver(new Observable.Observer<String>() {
@Override
public void update(Observable<String> o, String org) {
System.out.println(o + " is clicked");
}
});
button.onClick();
button.onClick();
button.onClick();
}
}
실행결과
com.bkjeon.observer.example3.Observable@15aeb7ab is clicked
com.bkjeon.observer.example3.Observable@15aeb7ab is clicked
com.bkjeon.observer.example3.Observable@15aeb7ab is clicked
반응형
'Java & Kotlin > Java' 카테고리의 다른 글
[Design Pattern] State Pattern (0) | 2020.01.10 |
---|---|
[Design Pattern] Mediator Pattern (0) | 2020.01.08 |
[Design Pattern] Facade Pattern (0) | 2020.01.04 |
[Design Pattern] Chain of Responsibility Pattern (0) | 2020.01.04 |
[Design Pattern] Visitor Pattern (0) | 2020.01.01 |
Comments