Java设计模式之观察者模式
1. 什么是观察者模式
观察者模式是一种行为型设计模式,它允许一个或多个对象在状态发生改变时自动通知其他对象。
在观察者模式中,存在两种角色:
- Subject(目标):负责发布通知的角色,可以添加,删除观察者,并通知观察者状态的变化。
- Observer(观察者):当被观察的对象的状态发生变化时,它会自动接收到通知并进行相应的处理。
2. 观察者模式的优缺点
优点
- 解耦。观察者模式可以使观察者和目标之间解耦,目标只关心自己的状态变化,而不需要了解观察者的情况。
- 可扩展。可以增加观察者和目标的数量,而不需要改变他们的代码。
- 一致性。观察者模式使得目标和观察者之间保持一致性,因为观察者可以按照目标的数据结构重新构造自己的状态。
- 开闭原则。新的观察者可以被加入到系统中,而不需要修改原有的代码。
缺点
- 观察者过多会导致系统效率降低。
- 如果目标跟观察者耦合度过高,会导致目标的变化会带来额外的消息量。
3. 示例说明
示例一:新闻发布
Subject:发布新闻的机构,可以添加,删除观察者,并在有新闻时通知所有已注册的观察者。
public class NewsPublisher {
private List<NewsSubscriber> subscribers = new ArrayList<>();
public void subscribe(NewsSubscriber subscriber) {
subscribers.add(subscriber);
}
public void unsubscribe(NewsSubscriber subscriber) {
subscribers.remove(subscriber);
}
public void publishNews(String news) {
System.out.println("新闻发布:" + news);
// 通知所有观察者
for (NewsSubscriber subscriber : subscribers) {
subscriber.update(news);
}
}
}
Observer:新闻订阅者,可以接收发布机构发布的新闻。
public class NewsSubscriber {
private String name;
public NewsSubscriber(String name) {
this.name = name;
}
public void update(String news) {
System.out.println(name + " 收到新闻:" + news);
}
}
测试方法:
NewsPublisher publisher = new NewsPublisher();
NewsSubscriber s1 = new NewsSubscriber("小明");
NewsSubscriber s2 = new NewsSubscriber("小红");
publisher.subscribe(s1);
publisher.subscribe(s2);
publisher.publishNews("今天天气晴朗,适合外出旅游");
publisher.unsubscribe(s1);
publisher.publishNews("下雨了,注意交通安全");
输出结果:
新闻发布:今天天气晴朗,适合外出旅游
小明 收到新闻:今天天气晴朗,适合外出旅游
小红 收到新闻:今天天气晴朗,适合外出旅游
新闻发布:下雨了,注意交通安全
小红 收到新闻:下雨了,注意交通安全
可以看到,两个新闻订阅者都收到了发布机构发布的新闻,当有订阅者取消订阅后也不会再收到通知。
示例二:气象站
Subject:气象站,可以添加,删除观察者,并在气象数据更新时通知所有已注册的观察者。
public class WeatherStation {
private List<WeatherObserver> observers = new ArrayList<>();
private float temperature;
private float humidity;
private float pressure;
public void registerObserver(WeatherObserver observer) {
observers.add(observer);
}
public void removeObserver(WeatherObserver observer) {
observers.remove(observer);
}
public void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
private void notifyObservers() {
for (WeatherObserver observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
}
Observer:气象数据展示面板,可以接收气象站的更新数据并显示。
public class WeatherDisplay implements WeatherObserver {
private float temperature;
private float humidity;
private float pressure;
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display();
}
public void display() {
System.out.println("当前气象数据:温度 " + temperature + " °C,湿度 " + humidity + "%,气压 " + pressure + " Pa");
}
}
测试方法:
WeatherStation station = new WeatherStation();
WeatherObserver observer1 = new WeatherDisplay();
WeatherObserver observer2 = new WeatherDisplay();
station.registerObserver(observer1);
station.registerObserver(observer2);
station.setMeasurements(25f, 50f, 100f);
station.setMeasurements(30f, 60f, 120f);
station.removeObserver(observer2);
station.setMeasurements(35f, 70f, 140f);
输出结果:
当前气象数据:温度 25.0 °C,湿度 50.0%,气压 100.0 Pa
当前气象数据:温度 30.0 °C,湿度 60.0%,气压 120.0 Pa
当前气象数据:温度 35.0 °C,湿度 70.0%,气压 140.0 Pa
可以看到,两个气象数据面板都显示出了气象站更新的数据,当有展示面板取消观察后也不再收到通知。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java设计模式之观察者模式_动力节点Java学院整理 - Python技术站