定义
观察者模式是定义了多个对象之间的一种一对多的依赖,当一个对象发生状态变更时,其他依赖他的所有对象会收到通知并自动更新
例子
类图
主题观察者代码
主题代码如下
主题接口
package com.example.design.pattern.book.observer;
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserver();
}
具体主题实现
package com.example.design.pattern.book.observer;
import java.util.ArrayList;
import java.util.List;
public class ConcreteSubject implements Subject {
private List<Observer> observers;
private int temp;
private int press;
private int hum;
public ConcreteSubject() {
this.observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
int index = observers.indexOf(observer);
observers.remove(index);
}
@Override
public void notifyObserver() {
observers.forEach(
observer -> {
observer.update(temp, press, hum);
}
);
}
public void setMeasuresChange(int temp, int press, int hum) {
this.temp = temp;
this.hum = hum;
this.press = press;
notifyObserver();
}
}
观察者代码如下
观察者接口
package com.example.design.pattern.book.observer;
public interface Observer {
void update(int temp, int press, int hum);
}
具体观察者1
package com.example.design.pattern.book.observer;
public class Observer1 implements Observer {
private Subject subject;
private int temp;
private int press;
private int hum;
public Observer1(Subject subject) {
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update(int temp, int press, int hum) {
this.temp = temp;
this.press = press;
this.hum = hum;
System.out.println("Observer1 update" + temp + press + hum);
}
}
具体观察者2
package com.example.design.pattern.book.observer;
public class Observer2 implements Observer {
private Subject subject;
private int temp;
private int press;
private int hum;
public Observer2(Subject subject) {
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update(int temp, int press, int hum) {
this.temp = temp;
this.press = press;
this.hum = hum;
System.out.println("Observer2 update" + temp + press + hum);
}
}
具体观察者3
package com.example.design.pattern.book.observer;
public class Observer3 implements Observer {
private Subject subject;
private int temp;
private int press;
private int hum;
public Observer3(Subject subject) {
this.subject = subject;
subject.registerObserver(this);
}
@Override
public void update(int temp, int press, int hum) {
this.temp = temp;
this.press = press;
this.hum = hum;
System.out.println("Observer3 update" + temp + press + hum);
}
}
利用java内置的主题观察者代码
具体的主题对象
package com.example.design.pattern.book.observer.inner;
import com.example.design.pattern.book.observer.Observer;
import com.example.design.pattern.book.observer.Subject;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
public class ConcreteSubject extends Observable {
//状态
private int temp;
private int press;
private int hum;
public ConcreteSubject() {
}
//当温度压力等发生改变时调用此函数
public void measureChanged(int temp, int press, int hum) {
this.temp = temp;
this.press = press;
this.hum = hum;
measure();
}
private void measure(){
// 更新观察者时有更多 的弹性,可以在适当的时候(当某一状态>=1时)通知观察者,而不是不断通知
setChanged();
notifyObservers();
}
//便于观察者获取更新的内容
public int getTemp() {
return temp;
}
public int getPress() {
return press;
}
public int getHum() {
return hum;
}
}
具体的观察者1
package com.example.design.pattern.book.observer.inner;
import java.util.Observable;
import java.util.Observer;
public class Observer1 implements Observer {
private Observable observable;
public Observer1(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
ConcreteSubject subject = (ConcreteSubject) o;
System.out.println("Observer1 update" + subject.getTemp() + subject.getPress() + subject.getHum());
}
}
具体的观察者2
package com.example.design.pattern.book.observer.inner;
import com.example.design.pattern.book.observer.Subject;
import java.util.Observable;
import java.util.Observer;
public class Observer2 implements Observer {
private Observable observable;
public Observer2(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
ConcreteSubject subject = (ConcreteSubject) o;
System.out.println("Observer2 update" + subject.getTemp() + subject.getPress() + subject.getHum());
}
}
具体的观察者3
package com.example.design.pattern.book.observer.inner;
import java.util.Observable;
import java.util.Observer;
public class Observer3 implements Observer {
private Observable observable;
public Observer3(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
ConcreteSubject subject = (ConcreteSubject) o;
System.out.println("Observer3 update" + subject.getTemp() + subject.getPress() + subject.getHum());
}
}
分析java内置
- 只会当changed为true的时候通知,通知后置为false状态
- setChanged(); 是置状态为true的方法
- 注意最坏情况:
- 当前观察者 赋值给 临时数组变量 会导致此后新增的观察者不会收到通知,此后删除的观察者会被通知