设计模式的学习(二)

xiaoxiao2021-02-28  99

今天好悲催,写了一大堆的东西没有了。算了,这一篇博客就长话短说吧。

观察者模式的主要针对场景HeadFirst Design Pattern 书中示例观察者模式的具体实现

观察者模式主要针对场景

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

HeadFirst Design Pattern 书中示例

HeadFirst Design Pattern 书中给出的给出的例子是,气象台提供了天气数据(温度,湿度),然后两个天气指示牌:当前天气指示牌, 天气状况统计指示牌。这两个指示牌都要求获得气象台提供的天气数据的更新并展示出来。当然,和上一节一样,我们依然需要考虑”change”这一法则,即假如加入一块新的天气指示牌(如天气预告指示牌)的场景。所以依然需要考虑代码的扩展和维护。 在简单的考虑后,我们可能会这样做:在提供天气数据的类(WeatherData类)中,加入CurrentWeatherDisplay类的实例对象的引用,并调用更新天气状况( update(int temperature ,int humidty) )的方法。对于天气统计状况指示牌也是一样处理。 但是这种设计有一种不好的地方就是,违反了上一篇博客所说内容。

针对接口编程,而非针对实现编程。

假如我们要加入一块新的天气指示牌,那么WeatherData类就需要发生更改了,也就不符合开闭原则了。

观察者模式的具体实现

直接贴出代码如下:

//两个接口代表被观察者和观察者 public interface Subject{ public void addObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); } public interface Observer{ public void update(int temperature, int humidity); } //天气数据(被观察者) import java.util.ArrayList; public class WeatherData implements Subject{ private int temperature; private int humidity; private ArrayList<Observer> observers = new ArrayList<Observer>(); public int getTemperature(){ return temperature; } public int getHumidity(){ return humidity; } public void addObserver(Observer o){ observers.add(o); } public void removeObserver(Observer o){ int i = observers.indexOf(o); if(i >= 0){ observers.remove(i); } } public void notifyObservers(){ for(int i = 0; i < observers.size(); i++){ Observer observer = observers.get(i); observer.update(temperature, humidity); } } public void measurementsChanged(int temperature, int humidity){ this.temperature = temperature; this.humidity = humidity; notifyObservers(); } } //当前天气展示板(观察者) public class CurrentConditionDisplay implements Observer{ private Subject weatherData; public CurrentConditionDisplay(Subject weatherData){ this.weatherData = weatherData; weatherData.addObserver(this); } public void update(int temperature, int humidity){ System.out.println("the temperature now is: " + temperature); System.out.println("the humidity now is: " + humidity + "%"); } } //统计天气展示板(观察者) public class StatisticConditionDisplay implements Observer{ private Subject weatherData; private int number = 0; private int temp_average = 0; private int humi_average = 0; public StatisticConditionDisplay(Subject weatherData){ this.weatherData = weatherData; weatherData.addObserver(this); } public void update(int temperature, int humidity){ number++; temp_average = (temp_average + temperature)/number; humi_average = (humi_average + humidity)/number; System.out.println("the average temperature is: " + temp_average); System.out.println("the average humidity is: " + humi_average + "%"); } }

对上述代码进行测试(加入当前天气展示板):

public class WeatherStation{ public static void main(String args[]){ WeatherData weatherData = new WeatherData(); CurrentConditionDisplay currentConditionDisplay = new CurrentConditionDisplay(weatherData);//注册观察者对象 weatherData.measurementsChanged(20, 40); } }

测试结果为:

从以上代码可以知道,这种设计模式的可扩展性是很强的。当你需要实现一个新的功能(如添加天气预报指示板),那么只需要在气象站里面对天气数据对象注册一个新的指示板对象即可。如下代码所示:

public class WeatherStation{ public static void main(String args[]){ WeatherData weatherData = new WeatherData(); CurrentConditionDisplay currentDisplay = new CurrentConditionDisplay(weatherData); StatisticConditionDisplay statisticDisplay = new StatisticConditionDisplay(weatherData);//注册统计天气展示板 weatherData.setMeasurements(20, 40); weatherData.setMeasurements(30, 50); } }

测试结果为:

从上述现象中可以发现,观察者模式的可扩展性是非常强的,当需要增加(或注销)观察者时,仅需要在代码中注册(或取消注册)具体的观察者对象即可。

转载请注明原文地址: https://www.6miu.com/read-60792.html

最新回复(0)