diff --git a/notes/设计模式.md b/notes/设计模式.md index f0137d3a..ced55bd4 100644 --- a/notes/设计模式.md +++ b/notes/设计模式.md @@ -610,6 +610,131 @@ public class Client { 定义对象之间的一对多依赖,当一个对象状态改变时,它的所有依赖都会收到通知并且自动更新状态。 +主题(Subject)是被观察的对象,而其所有依赖者(Observer)称为观察者。 + +

+ +### 类图 + +主题(Subject)具有注册和移除观察者、并通知所有注册者的功能,主题是通过维护一张观察者列表来实现这些操作的。 + +观察者(Observer)的注册功能需要调用主题的 registerObserver() 方法。 + +

+ +### 实现 + +天气数据布告板会在天气信息发生改变时更新其内容,布告板有多个,并且在将来会继续增加。 + +

+ +```java +public interface Subject { + void resisterObserver(Observer o); + + void removeObserver(Observer o); + + void notifyObserver(); +} +``` + +```java +import java.util.ArrayList; +import java.util.List; + +public class WeatherData implements Subject { + private List observers; + private float temperature; + private float humidity; + private float pressure; + + public WeatherData() { + observers = new ArrayList<>(); + } + + public void setMeasurements(float temperature, float humidity, float pressure) { + this.temperature = temperature; + this.humidity = humidity; + this.pressure = pressure; + notifyObserver(); + } + + @Override + public void resisterObserver(Observer o) { + observers.add(o); + } + + @Override + public void removeObserver(Observer o) { + int i = observers.indexOf(o); + if (i >= 0) { + observers.remove(i); + } + } + + @Override + public void notifyObserver() { + for (Observer o : observers) { + o.update(temperature, humidity, pressure); + } + } +} +``` + +```java +public interface Observer { + void update(float temp, float humidity, float pressure); +} +``` + +```java +public class StatisticsDisplay implements Observer { + + public StatisticsDisplay(Subject weatherData) { + weatherData.resisterObserver(this); + } + + @Override + public void update(float temp, float humidity, float pressure) { + System.out.println("StatisticsDisplay.update: " + temp + " " + humidity + " " + pressure); + } +} +``` + +```java +public class CurrentConditionsDisplay implements Observer { + + public CurrentConditionsDisplay(Subject weatherData) { + weatherData.resisterObserver(this); + } + + @Override + public void update(float temp, float humidity, float pressure) { + System.out.println("CurrentConditionsDisplay.update: " + temp + " " + humidity + " " + pressure); + } +} +``` + +```java +public class WeatherStation { + public static void main(String[] args) { + WeatherData weatherData = new WeatherData(); + CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData); + StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); + + weatherData.setMeasurements(0, 0, 0); + weatherData.setMeasurements(1, 1, 1); + } +} +``` + +```html +CurrentConditionsDisplay.update: 0.0 0.0 0.0 +StatisticsDisplay.update: 0.0 0.0 0.0 +CurrentConditionsDisplay.update: 1.0 1.0 1.0 +StatisticsDisplay.update: 1.0 1.0 1.0 +``` + ### JDK - [java.util.Observer](http://docs.oracle.com/javase/8/docs/api/java/util/Observer.html) diff --git a/pics/48a934ff-a29b-434c-8e1d-8c8ec20cb91d.png b/pics/48a934ff-a29b-434c-8e1d-8c8ec20cb91d.png new file mode 100644 index 00000000..9c6b68dc Binary files /dev/null and b/pics/48a934ff-a29b-434c-8e1d-8c8ec20cb91d.png differ diff --git a/pics/7a3c6a30-c735-4edb-8115-337288a4f0f2.jpg b/pics/7a3c6a30-c735-4edb-8115-337288a4f0f2.jpg new file mode 100644 index 00000000..8d40765e Binary files /dev/null and b/pics/7a3c6a30-c735-4edb-8115-337288a4f0f2.jpg differ diff --git a/pics/b1df9732-86ce-4d69-9f06-fba1db7b3b5a.jpg b/pics/b1df9732-86ce-4d69-9f06-fba1db7b3b5a.jpg new file mode 100644 index 00000000..a71d167e Binary files /dev/null and b/pics/b1df9732-86ce-4d69-9f06-fba1db7b3b5a.jpg differ