设计模式观察者模式
Posted torjan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式观察者模式相关的知识,希望对你有一定的参考价值。
观察者模式 定义了对象之间的一对多的依赖,这样一来,当一个对象状态改变时,他的
多有依赖都会受到通知并自动更新。
本例为一个温度基站,和三个终端。温度基站为广播类WeatherData,三个终端监听者类分别为:TVDispaly,FactoryDisplay,MobileDisplay
其中,Observable为广播类父类,含有基本的方法。
Observer类为监听者接口,监听者需实现updata方法。
Display为显示接口,需实现display方法。
ObserverDemo为测试类。
下面直接上代码,注释很清晰。基本上很容易理解。
Observable.java
package observer; /* * @author trojan * 广播类的父类 * */ public class Observable { protected boolean change = false; public void setChanged() { change = true; } public void notifyObservers(Object arg) {} public void notifyObservers(){ notifyObservers(null);} public void addObserver(Observer observer){} }
WeatherData.java
package observer; /* * @author trojan * 该类为广播类 */ import java.util.ArrayList; public class WeatherData extends Observable { //温度 private float temperature; //湿度 private float humidity; //污染指数 private float pollution_index; ArrayList<Observer> observers = new ArrayList<Observer>(); public WeatherData(){ } //增加监听者 public void addObserver(Observer observer){ observers.add(observer); } //将更改广播给所有监听者 public void notifyObservers(Object arg) { if(change){ for(Observer observer : observers){ observer.update(this,arg); } } change = false; } public void notifyObservers() { notifyObservers(null);} public void stateChange() { //调用notifyObservers之前应调用状态改变标志函数 setChanged(); notifyObservers(); } //设置状态后,将调用stateChange函数,通知监听者 public void setState(float temperature, float humidity, float pollution_index) { this.temperature = temperature; this.humidity = humidity; this.pollution_index = pollution_index; stateChange(); } public float getTemperature() { return temperature; } public void setTemperature(float temperature) { this.temperature = temperature; } public float getHumidity() { return humidity; } public void setHumidity(float humidity) { this.humidity = humidity; } public float getPollution_index() { return pollution_index; } public void setPollution_index(float pollution_index) { this.pollution_index = pollution_index; } }
Display.java
package observer; /* * @author * 显示接口 */ public interface Display { public void display(); }
Observer.java
package observer; /* * @author trojan * 这是一个监听者的接口,需要实现updata方法 * 该方法可以被广播者调用,向监听者广播数据,或者说是一种推的方式 * 监听者可以可以调用该方法主动更新数据,就像是一种拉的方式 * 当然,对于每一个实现的监听者可能会有不同的数据需求 * 所以,他们可以实现对自己感兴趣的那部分数据更新 * */ public interface Observer { public void update(Object obj,Object arg);; }
TVDisplay.java
package observer; /* * @author trojan * 对于电视台来说可能需要的气象数据要比其他的设备多 * 所以updata需要更新更多的数据 */ public class TVDisplay implements Observer, Display{ Observable observable; private float temperature; private float humidity; private float pollution_index; //变成一个监听者 public void becomeOberser(Observable observable) { this.observable = observable; observable.addObserver(this);; } @Override public void update(Object obj, Object arg) { if(obj instanceof WeatherData){ WeatherData weatherData = (WeatherData)obj; this.temperature = weatherData.getTemperature(); this.humidity = weatherData.getHumidity(); this.pollution_index = weatherData.getPollution_index(); } } @Override public void display() { System.out.println("WeatherData:\n" + "temperature: "+temperature +"\n" +"humidity"+humidity+"\n" +"pollution_index:"+pollution_index); } }
FactoryDisplay.java
package observer; /* * @author torjan * 工厂显示平台所需要的广播数据 * */ public class FactoryDisplay implements Observer, Display{ Observable observable; private float temperature; private float pollution_index; //变成一个监听者 public void becomeOberser(Observable observable) { this.observable = observable; observable.addObserver(this);; } @Override public void update(Object obj, Object arg) { if(obj instanceof WeatherData){ WeatherData weatherData = (WeatherData)obj; this.temperature = weatherData.getTemperature(); this.pollution_index = weatherData.getPollution_index(); } } @Override public void display() { System.out.println("WeatherData:\n" + "temperature: "+temperature +"\n" +"pollution_index"+pollution_index); } }
MobileDisplay.java
package observer; /* * @author * 手机平台所需要的广播数据 * */ public class MobileDisplay implements Observer, Display { Observable observable; private float temperature; private float humidity; //变成一个监听者 public void becomeOberser(Observable observable) { this.observable = observable; observable.addObserver(this);; } @Override public void update(Object obj, Object arg) { if(obj instanceof WeatherData){ WeatherData weatherData = (WeatherData)obj; this.temperature = weatherData.getTemperature(); this.humidity = weatherData.getHumidity(); } } @Override public void display() { System.out.println("WeatherData:\n" + "temperature: "+temperature +"\n" +"humidity"+humidity); } }
测试类:
ObserverDemo.java
package observer; public class ObserverDemo { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); FactoryDisplay factoryDisplay = new FactoryDisplay(); MobileDisplay mobileDisplay = new MobileDisplay(); TVDisplay tvDisplay = new TVDisplay(); weatherData.addObserver(factoryDisplay); weatherData.addObserver(mobileDisplay);; tvDisplay.becomeOberser(weatherData); weatherData.setState(23, 70, 120); factoryDisplay.display(); mobileDisplay.display(); tvDisplay.display(); } }
测试结果:
WeatherData: temperature: 23.0 pollution_index120.0 WeatherData: temperature: 23.0 humidity70.0 WeatherData: temperature: 23.0 humidity70.0 pollution_index:120.0
总结:
设计原则:找出程序中会变化的方面,然后根据其和固定不变的方面相分离
在观察者模式中,会改变的是主题的状态,以及观察者的数目和种类。用这个模式,可以改变依赖于主题状态的对象,却不必改变主题。
设计原则:针对接口编程,不针对实现编程
设计原则:多用组合,少用继承
以上是关于设计模式观察者模式的主要内容,如果未能解决你的问题,请参考以下文章
Java设计模式补充:回调模式事件监听器模式观察者模式(转)