本文是《【C++】观察者模式》(点击打开链接)的Java实现,关于什么是观察者模式这里就不将了,只是从类图为视觉重新审视这条2014年上半年的软件设计师的软考题。
题目是这样的:
某实验室欲建立一个实验室的环境监测系统,能够显示实验室的温度、湿度以及洁净度等环境数据,当获取到最新的环境测量数据时,显示的环境数据能够更新,现在采用观察者(Observer)模式来开发该系统,观察者模式的类图如图5-1所示:
代码还是在做一件通过修改具体主题类的类成员,达到自动更新具体观察类的类成员事情。
从类图可以看到ConcreteSubject与ConcreteObserver是分别实现Subject与Observer两个接口的,因为其继承线段是虚线。
同时观察者与主题之间是关联关系,也就是说在观察者类中必有主题这个类成员,主题类中必有观察者这个类成员。
而且观察者是是通过register与interest来操作主题,主题则通过update来操作观察者。
具体实现代码如下:
import java.util.*; //接口 interface Observer{ public void update(float temp,float humidity,float cleanness); } interface Subject{ public void registerObserver(Observer o);//注册对主题感兴趣的观察者 public void removeObserver(Observer o);//删除观察者 public void notifyObservers();//当主题发生变化时通知观察者 } //具体主题 class EnvironmentData implements Subject{ private ArrayList<Observer> observers; private float temperature,humidity,cleanness; public EnvironmentData(){ observers=new ArrayList<Observer>(); } @Override public void registerObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { observers.remove(o); } @Override public void notifyObservers() { for (int i = 0; i < observers.size(); i++) { Observer observer=(Observer)observers.get(i); observer.update(temperature, humidity, cleanness);//用于改变队列中所有Observer的类成员 } } //改变主题属性的同时,将队列中所有观测者的类成员改变 public void setMeasurements(float temperature,float humidity,float cleanness){ this.temperature=temperature; this.humidity=humidity; this.cleanness=cleanness; notifyObservers(); } } //具体观察者 class CurrentConditionsDisplay implements Observer{ private String NAME="观察者1"; private float temperature; private float humidity; private float cleanness; private Subject envData; public CurrentConditionsDisplay(Subject envData,String NAME) {//构造方法 this.envData=envData; this.envData.registerObserver(this);//在主题的观察者队列中注册自己 this.NAME=NAME; } public void update(float temperature,float humidity,float cleanness){ this.temperature=temperature; this.humidity=humidity; this.cleanness=cleanness; } public void display() { System.out.println("我是"+NAME+",现在的温度是:"+temperature+",显示的湿度是:"+humidity+",现在的洁净度是:"+cleanness); } } //主函数 public class EnvironmentMonitor { public static void main(String[] args) { EnvironmentData envData=new EnvironmentData(); CurrentConditionsDisplay currentDisplay1=new CurrentConditionsDisplay(envData,"观察者1"); CurrentConditionsDisplay currentDisplay2=new CurrentConditionsDisplay(envData,"观察者2"); envData.setMeasurements(80, 65, 30.4f); currentDisplay1.display(); currentDisplay2.display(); } }