盒子
盒子
文章目录
  1. 1. 定义主题
  2. 2. 定义观察者
  3. 3. 实现主题
  4. 4. 实现观察者
  5. 5. JDK自带观察者方式实现

观察者模式

观察者模式,定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新

1. 定义主题

1
2
3
4
5
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserver();
}

2. 定义观察者

1
2
3
public interface Observer {
void update(float temperature, float humidity, float pressure);
}

3. 实现主题

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class WeatherData implements Subject {
private float temperature;
private float humidity;
private float pressure;
private List<Observer> observers;

public WeatherData() {
observers = new ArrayList<>();
}

@Override
public void registerObserver(Observer observer) {
if (null == observer) {
return;
}
if (!observers.contains(observer)) {
observers.add(observer);
}
}

@Override
public void removeObserver(Observer observer) {
if (observers.indexOf(observer) != -1) {
observers.remove(observer);
}
}

@Override
public void notifyObserver() {
observers.forEach(observer -> {
observer.update(temperature, humidity, pressure);
});
}

public void setMeasurements(float temperature,float humidity,float pressure){
this.temperature=temperature;
this.humidity=humidity;
this.pressure=pressure;
measurementsChanged();
}

private void measurementsChanged() {
notifyObserver();
}
}

4. 实现观察者

1
2
3
public interface DisplayElement {
void display();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private Subject weatherData;

public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}

@Override
public void display() {
System.out.println("Current conditions: " + temperature + "F degree and " + humidity + "% humidity");
}

@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
}

5. JDK自带观察者方式实现

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
32
import java.util.Observable;
import java.util.Observer;

public class WeatherData extends Observable {
private float temperature;
private float humidity;
private float pressure;

public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure =pressure;
measurementsChanged();
}

private void measurementsChanged() {
setChanged();
notifyObservers();
}

public float getTemperature() {
return temperature;
}

public float getHumidity() {
return humidity;
}

public float getPressure() {
return pressure;
}
}
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
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private Observable observable;
private float temperature;
private float humidity;

public CurrentConditionsDisplay(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}

@Override
public void update(Observable observable, Object arg) {
if (observable instanceof WeatherData) {
WeatherData weatherData = (WeatherData) observable;
// 观察者主动的拉取想要的消息
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
display();
}
}

@Override
public void display() {
System.out.println("Current conditions: " + temperature + "F degree and " + humidity + "% humidity");
}
}

体现设计原则:为了交互对象之间的松耦合设计而努力
虽然jdk也自带了Observer与Observable,但不建议使用,其违反了多用组合,少用继承设计规则。 从该气象站实例中,得不到正确的通知结果(JDK自带倒叙输出),并且当某一观察者update异常时,未正确捕获将导致其他通知失败,而自定义可以在notifyObserver()中统一捕获处理

支持一下
扫一扫,支持沈健
  • 微信扫一扫
  • 支付宝扫一扫