设计模式5之(观察者模式)
观察者模式(设计模式)
若有不恰之处,请各位道友指正~
个人觉得,看懂类图就是学习设计模式的精髓了。
观察者模式概念
- 定义了对象之间的一对多依赖,这样一来,当一个对象发生改变时,它的所有依赖都可以收到通知,并自动更新
根据类图写代码
代码结构
// 主题
public interface Subject {
public void addObserver(Observer o);
public void removeObserver(Observer o);
public void sendAllObserver();
}
//主题的实现类
public class WeatherData implements Subject {
private float humidity;
private float temp;
private float pressure;
private List observerList;
public WeatherData(){
observerList = new ArrayList<>();
}
@Override
public void addObserver(Observer o) {
observerList.add(o);
}
@Override
public void removeObserver(Observer o) {
int i = observerList.indexOf(o);
if(i>0){
observerList.remove(o);
}
}
@Override
public void sendAllObserver() {
if(observerList.size() > 0){
for(int i=0;i<observerList.size();i++) {
Observer o = (Observer) observerList.get(0);
o.update(temp,pressure,humidity);
}
}
}
public void setMeasurement(float temp,float pressure,float humidity){
this.humidity = humidity;
this.pressure = pressure;
this.temp = temp;
sendAllObserver();
}
}
//接收者
public interface Observer {
void update(float temp,float pressure,float humidity);
}
//接收者实现
public class FirstObserver implements Observer {
private Subject subject;
public FirstObserver(Subject subject){
// this.subject = subject;
subject.addObserver(this);
}
@Override
public void update(float temp, float pressure, float humidity) {
System.out.println("第一个观察者");
System.out.println("温度为:"+temp);
System.out.println("气压为:"+pressure);
System.out.println("湿度为:"+humidity);
}
}
//测试类
public class ObserverTest {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
FirstObserver firstObserver = new FirstObserver(weatherData);
weatherData.setMeasurement(22.2f,100001.2f,78.0f);
}
}
观察者模式(jdk 提供Observer接口)
先看看jdk 提供的Observable接口类,他提供了的几方法:
- addObserver
- deleteObserver
- notifyObservers 最后调用的方法即是Observer 接口的update方法
- setChanged 该方法在notifyObservers方法前调用,类似flag标记设置的作用
- clearChanged
而Observer接口,只有一个update 方法
代码结构
//主题实现类
public class WeatherData extends Observable {
private float humidity;
private float pressure;
private float temp;
public WeatherData(){}
public void setMeasurementsChange(float humidity,float pressure,float temp){
this.humidity = humidity;
this.pressure = pressure;
this.temp = temp;
measurementChanged();
}
public void measurementChanged(){
setChanged();//该方法就是作为调用标记(flag)存在。
notifyObservers();// 这边方法往里面链,发现最后调用的就是Observer 的 update 方法
}
public Float getHumidity(){
return humidity;
}
public Float getPressure(){
return pressure;
}
public Float getTemp(){
return temp;
}
}
//接收者实现类
public class SecondObserver implements Observer {
public SecondObserver(Observable observable){
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
if(o instanceof WeatherData){
Float humidity = ((WeatherData) o).getHumidity();
Float pressure = ((WeatherData) o).getPressure();
System.out.println("湿度:"+humidity);
System.out.println("气压:"+pressure);
}
}
}
//测试类
public class ObserverTest {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
SecondObserver secondObserver = new SecondObserver(weatherData);
weatherData.setMeasurementsChange(123.1f,22222.3f,78f);
}
}
java.util.Observable 的黑暗
- Observable 是一个类,不是接口,先知了复用能力
- setChanged 是 projected 方法,只能用继承使用该方法,违法了“多用组合,少用继承”