Talk is cheap.Show me your code.资料

本文主要介绍Talk is cheap.Show me your code.资料 方法和在新技术下所面对的“挑战”,方便大家深入理解Talk is cheap.Show me your code.资料 过程。本文也将分享Talk is cheap.Show me your code.资料 所遇到的问题和应对策略,怎么解决怎么做的问题。
通过深入本文可以理解代码原理,进行代码文档的下载,也可以查看相应 Demo 部署效果。

基本介绍

观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)

意图:当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。

观察者模式属于行为型模式, 大多应用于一些事件驱动模型(Spring涉及)或者游戏开发领域。

 

假设有一家气象局,姑且就叫神盾气象局吧,该气象局委托我们构建一套系统,这个系统有两个公告牌,需要我们显示当前的实时天气和未来的天气预报。 当神盾气象局发布新的天气数据(WeatherData)后,两个公告牌上显示的天气数据务必实时更新。神盾气象局同时要求我们保证程序拥有足够的可扩展性,因为以后随时要新增其他的公告牌(如紧急公告等)。

它们的最初始的设计如下:

public class WeatherData {      //实例变量声明     ...     public void measurementsChanged() {              float temperature = getTemperature();         float humidity = getHumidity();         float pressure = getPressure();         List<Float> forecastTemperatures = getForecastTemperatures();                  //更新公告牌         currentConditionsDisplay.update(temperature, humidity, pressure);         forecastDisplay.update(forecastTemperatures);     }     ... } 

 

然鹅每当我需要删除或者新增公告牌时,我就必须得修改 核心逻辑代码,如此看来扩展性极差,违背了开闭原则(对扩展开放,对修改关闭)

从上述方案,我们已经大致了解该方案有很多问题

  • 扩展性较差
  • 代码功能耦合严重
  • 核心功能代码改来改去容易出问题

 

观察者模式

观察者模式通常情况所解决的需求场景:A对象(观察者)被 B对象(被观察者)的某种变化高度敏感,需要在B变化的那一刻A及时得到反馈。

举个例子:小明过马路,小明需要在红绿灯由红灯变成绿灯后到达马路另一侧,这个场景中,小明是观察者,红绿灯是被观察者,当红绿灯发生颜色改变时,小明需要得到反馈。

但是程序中的观察和现实中所说的【观察】有些许差异:

  • 观察者不需要时刻盯着被观察者(小明不需要每一秒盯着红绿灯)
  • 采用注册或者订阅(Subscribe)的方式告诉被观察者(红绿灯变色后会广播,小明可以听到)

采取这样被动的观察方式,省去了反复检索状态的资源消耗,也能得到最快的反馈速度,其实就是由拉变成了推

 

观察者模式通常基于 Subject(主题)和 Observer(观察者)而设计,类图如下

Talk is cheap.Show me your code.

 

既然我们说了神盾气象局最初的设计 多么的糟糕,那么我们现在就用观察者模式来重构它吧!

首先我们基于上述的通用类图,重新构建神盾气象局的结构类图以及编码实现

Talk is cheap.Show me your code.

 

主题接口

/**  * 主题  */ public interface Subject {      void registerObserver(Observer observer);      void removeObserver(Observer observer);      void notifyObserver();  } 

 

观察者接口

/**  * 观察者  */ public interface Observer {      //反向更新     void update(WeatherDetail weatherDetail);  } 

 

公告牌接口

public interface DisplayElement {      void display();  } 

 

气象数据Entity

@Data @AllArgsConstructor public class WeatherDetail {      private double temperature; //当前温度     private double humidity; //当前湿度     private double pressure; //当前气压     private List<WeatherDetail> forecastDetails;//未来几天的气象数据详情  } 

 

气象数据(被观察者)- 核心

@Data public class WeatherData implements Subject {      private List<Observer> observers;     private WeatherDetail weatherDetail;      public WeatherData() {         observers = new ArrayList<>();     }      @Override     public void registerObserver(Observer observer) {         observers.add(observer);     }      @Override     public void removeObserver(Observer observer) {         if (!observers.isEmpty()) {             observers.remove(observer);         }     }      @Override     public void notifyObserver() {         for (Observer observer : observers) {             observer.update(weatherDetail);         }     }      public void setMeasurements(WeatherDetail weatherDetail){         this.weatherDetail = weatherDetail;         notifyObserver();     }  } 

 

显示当前天气的公告牌(CurrentConditionDisplay)

/**  * 当前展板  */ public class CurrentConditionDisplay implements Observer, DisplayElement {      private double temperature; //当前温度     private double humidity; //当前湿度     private double pressure; //当前气压      public CurrentConditionDisplay(Subject weatherData) {         //天气数据         weatherData.registerObserver(this);     }      @Override     public void display() {         System.out.println("current-[temperature:" + temperature + ",humidity:" + humidity + ",pressure:" + pressure + "]");     }      @Override     public void update(WeatherDetail weatherDetail) {         this.temperature = weatherDetail.getTemperature();         this.humidity = weatherDetail.getHumidity();         this.pressure = weatherDetail.getPressure();     } } 

 

显示未来几天天气的公告牌(ForecastConditionDisplay)

ppublic class ForecastConditionDisplay implements Observer, DisplayElement {      private List<WeatherDetail> forecastDetails;//未来几天的气象数据详情      public ForecastConditionDisplay(Subject weatherData) {         weatherData.registerObserver(this);     }      @Override     public void display() {         if (forecastDetails != null) {             for (WeatherDetail weatherDetail : forecastDetails) {                 System.out.println("forecast-[temperature:" + weatherDetail.getTemperature()                         + ",humidity" + weatherDetail.getHumidity() + ",pressure" + weatherDetail.getPressure() + "]");             }         }     }      @Override     public void update(WeatherDetail weatherDetail) {         forecastDetails = weatherDetail.getForecastDetails();     } } 

 

到这里,我们整个神盾气象局的WeatherData应用就改造完成了。

两个公告牌 CurrentConditionsDisplayForecastConditionDisplay 实现了 ObserverDisplayElement 接口。在他们的构造方法中会调用 WeatherDataregisterObserver 方法将自己注册成观察者,这样被观察者 WeatherData 就会持有观察者的应用,并将它们保存到一个集合中。当被观察者 WeatherData 状态发生变化时就会遍历这个集合,循环调用观察者更新公告牌数据的方法。后面如果我们需要增加或者删除公告牌,就只需要新增或者删除实现了 ObserverDisplayElement 接口的公告牌就好了。

 

好,我们接下来测试一下利用观察者模式改进后的程序…..

public class Client { 	public static void main(String[] args) { 		List<WeatherDetail> forecastDetail = new ArrayList<>(); 		forecastDetail.add(new WeatherDetail(23.0, 0.9, 1.1, null)); 		forecastDetail.add(new WeatherDetail(17.0, 0.5, 1.3, null)); 		WeatherDetail weatherDetail = new WeatherDetail(22.0, 0.8, 1.2, forecastDetail); 		WeatherData weatherData = new WeatherData(); 		DisplayElement current = new CurrentConditionDisplay(weatherData); 		DisplayElement forecast = new ForecastConditionDisplay(weatherData); 		weatherData.setMeasurements(weatherDetail);  		current.display(); 		forecast.display(); 	} } 

输出结果
Talk is cheap.Show me your code.
 

观察者模式(JDK版)

我们还是用神盾气象局的例子来实现JDK版本的观察者模式,这样便于比较两者之间的差别
 
公告牌接口

public interface DisplayElement {      void display();  } 

 
气象数据Entity

@Data @AllArgsConstructor public class WeatherDetail {      private double temperature; //当前温度     private double humidity; //当前湿度     private double pressure; //当前气压     private List<WeatherDetail> forecastDetails;//未来几天的气象数据详情  } 

 
气象数据(被观察者)- 核心

/**  * 天气数据  */ @Data public class WeatherData extends Observable {      private WeatherDetail weatherDetail;      public WeatherData() {}       public void setMeasurements(WeatherDetail weatherDetail){         this.weatherDetail = weatherDetail;         this.setChanged();         notifyObservers(weatherDetail);     }  } 

 
显示当前天气的公告牌(CurrentConditionDisplay)

/**  * 当前展板  */ public class CurrentConditionDisplay implements Observer, DisplayElement {      private double temperature; //当前温度     private double humidity; //当前湿度     private double pressure; //当前气压      public CurrentConditionDisplay(Observable weatherData) {         //天气数据         weatherData.addObserver(this);     }      @Override     public void display() {         System.out.println("current-[temperature:" + temperature + ",humidity:" + humidity + ",pressure:" + pressure + "]");     }       @Override     public void update(Observable observable, Object arg) {         WeatherDetail weatherDetail = (WeatherDetail) arg;         this.temperature = weatherDetail.getTemperature();         this.humidity = weatherDetail.getHumidity();         this.pressure = weatherDetail.getPressure();     } } 

 
显示未来几天天气的公告牌(ForecastConditionDisplay)

public class ForecastConditionDisplay implements Observer, DisplayElement {      private List<WeatherDetail> forecastDetails;//未来几天的气象数据详情      public ForecastConditionDisplay(Observable weatherData) {         //天气数据         weatherData.addObserver(this);     }      @Override     public void display() {         if (forecastDetails != null) {             for (WeatherDetail weatherDetail : forecastDetails) {                 System.out.println("forecast-[temperature:" + weatherDetail.getTemperature()                         + ",humidity:" + weatherDetail.getHumidity() + ",pressure:" + weatherDetail.getPressure() + "]");             }         }     }      @Override     public void update(Observable observable, Object arg) {         WeatherDetail weatherDetail = (WeatherDetail) arg;         this.forecastDetails = weatherDetail.getForecastDetails();     }  } 

 
到这里,我们使用JDK自带的API实现了观察者模式,下面我们开始测试

public class Client {     public static void main(String[] args) {         List<WeatherDetail> forecastDetail = new ArrayList<>();         forecastDetail.add(new WeatherDetail(23.0, 0.9, 1.1,null));         forecastDetail.add(new WeatherDetail(17.0, 0.5, 1.3,null));         WeatherDetail weatherDetail = new WeatherDetail(22.0, 0.8, 1.2, forecastDetail);         WeatherData weatherData = new WeatherData();         DisplayElement current = new CurrentConditionDisplay(weatherData);         DisplayElement forecast = new ForecastConditionDisplay(weatherData);         weatherData.setMeasurements(weatherDetail);          current.display();         forecast.display();     } } 

输出结果
Talk is cheap.Show me your code.
 
总结:使用JDK自带的API去实现观察者模式固然方便,但是由于需要继承 Observable 接口,会对被观察者类造成限制(单继承的局限性),其次 Observable 的代码 从属JDK1.0,底层还是用的相关的Vector去做安全的集合容器,个人感觉还是有点过时了,个人还是倾向于自实现观察者模式。

Talk is cheap.Show me your code.资料部分资料来自网络,侵权毕设源码联系删除

区块链毕设网(www.qklbishe.com)全网最靠谱的原创区块链毕设代做网站
部分资料来自网络,侵权联系删除!
资源收费仅为搬运整理打赏费用,用户自愿支付 !
qklbishe.com区块链毕设代做网专注|以太坊fabric-计算机|java|毕业设计|代做平台 » Talk is cheap.Show me your code.资料

提供最优质的资源集合

立即查看 了解详情