面向对象设计模式之一观察者模式

1.首先看观察者模式定义:

对象之间有一对多的依赖关系,一个对象状态改变,会通知其他对象,其他对象会自动更新。

2.主题对象(被观察者)提供观察接口,多个观察者实现此接口。

3.JDK中Swing,JavaBeans等都有使用该模式。

4.现在来看代码

5.先看主题接口Subject:定义一个接口

 1 package com.pattern.observer;
 2 /*
 3  * 主题接口,只知道有观察者观察它,对于观察者并不是很了解,主题对象要实现此接口
 4  * */
 5 public interface Subject {
 6     
 7     void registerObserver(Observer o);//注册观察者,或者说登记
 8     void removeObserver(Observer o);//取消一个观察者
 9     void notifyAllObserver();//通知所有观察者
10     
11 }

6.定义观察者接口Observer

1 package com.pattern.observer;
2 /*
3  * 观察者接口,所有的观察者都要实现这个接口,并实现接口里的uodate方法
4  */
5 public interface Observer {
6     void update(Object o);//所有的观察者都有更新自己的方法,主题对象会调用此方法把数据传给观察者
7 }

7.定义主题接口实现者(由自己实际决定)WeatherForecast

 1 package com.pattern.observer;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 /*
 7  * 主题对象,天气预报
 8  */
 9 public class WeatherForecast implements Subject {
10 
11     private List observers;//所有注册的观察者
12     private WeatherData data;//状态的引用
13     
14     
15     public WeatherForecast( WeatherData data) {
16         super();
17         this.observers = new ArrayList();
18         this.data = data;
19     }
20 
21     @Override
22     public void registerObserver(Observer o) {
23         observers.add(o);
24 
25     }
26 
27     @Override
28     public void removeObserver(Observer o) {
29         observers.remove(o);
30 
31     }
32 
33     //通知所有观察者
34     @Override
35     public void notifyAllObserver() {
36         for (Observer observer : observers) {
37             observer.update(data);
38         }
39 
40     }
41     
42     //从气象站获取的测量值发生改变会调用此方法
43     public void measurementDataChanged(){
44         notifyAllObserver();
45     }
46     //改变状态
47     public void setWeatherData(WeatherData data){
48         this.data = data;
49 
50     }
51 
52 }

8.定义主题对象的状态类,或者说是数据对象WeatherData

package com.pattern.observer;
/*
 * 天气数据封装类,或者说主题对象的状态封装类
 */
public class WeatherData {
    
    private float temperature;//温度数据,一个状态
    private float humidity;//湿度数据,一个状态
    private float pressure;//压力数据,一个状态
    
    
    public WeatherData(float temperature, float humidity, float pressure) {
        super();
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
    }
    
    public void setState(float temperature, float humidity, float pressure)
    {
        this.setTemperature(temperature);
        this.setHumidity(humidity);
        this.setPressure(pressure);
    }
    
    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 getPressure() {
        return pressure;
    }
    public void setPressure(float pressure) {
        this.pressure = pressure;
    }

}

9.定义所有的观察者类,我在此处定义了两个CurrentWeatherDisplay和FeatureWeather,代码如下

 1 package com.pattern.observer;
 2 /*
 3  * 观察者对象之一,当前天气显示面板
 4  */
 5 public class CurrentWeatherDisplay implements Observer {
 6     private WeatherData data;//接受传过来的数据对象
 7     private Subject sj;//表示要注册的主题或者说广播
 8 
 9     public CurrentWeatherDisplay(){
10         
11     }
12     public CurrentWeatherDisplay(Subject sj) {//构造方法需要主题作为注册之用
13         super();
14         this.sj = sj;
15         sj.registerObserver(this);//一旦创建好观察者对象就把注册到主题列表中
16     }
17     /*
18      * 把自己注册一个主题
19      */
20     public void register(Subject sj){
21         this.sj = sj;
22         sj.registerObserver(this);
23     }
24     /*
25      * 取消注册一个主题
26      */
27     public void unregister(Subject sj){
28         this.sj = sj;
29         sj.removeObserver(this);
30         this.sj = null;
31     }
32 
33     @Override
34     public void update(Object o) {
35         this.data = (WeatherData) o;
36         display();//天气数据一旦改变,马上更新面板
37     }
38     
39     public void display(){
40         System.err.println("目前的天气是--温度:"+data.getTemperature()+"湿度:"+data.getHumidity()+"气压:"+data.getPressure());
41     }
42 
43 }
 1 package com.pattern.observer;
 2 /*
 3  * 观察者对象之一,未来天气显示面板
 4  */
 5 public class FeatureWeather implements Observer {
 6     private WeatherData data;//接受传过来的数据对象
 7     private Subject sj;//表示要注册的主题或者说广播
 8 
 9     public FeatureWeather(){
10         
11     }
12     public FeatureWeather(Subject sj) {//构造方法需要主题作为注册之用
13         super();
14         this.sj = sj;
15         sj.registerObserver(this);//一旦创建好观察者对象就把注册到主题列表中
16     }
17     /*
18      * 把自己注册一个主题
19      */
20     public void register(Subject sj){
21         this.sj = sj;
22         sj.registerObserver(this);
23     }
24     /*
25      * 取消注册一个主题
26      */
27     public void unregister(Subject sj){
28         this.sj = sj;
29         sj.removeObserver(this);
30         this.sj = null;
31     }
32 
33     @Override
34     public void update(Object o) {
35         this.data = (WeatherData) o;
36         display();
37         
38     }
39     
40     public void display(){
41         System.err.println("未来几天的天气是--温度:"+data.getTemperature()+1.0+"-"+data.getTemperature()+10.0+"湿度:"+data.getHumidity()+2.0+"-"+data.getHumidity()+6.0+"气压:"+data.getPressure()+"-"+data.getPressure()+2.0);
42     }
43 
44 }

10.测试客户端代码

 1 package com.pattern.observer;
 2 /**
 3  * 客户端测试代码
 4  * @author Administrator
 5  *
 6  */
 7 public class Client {
 8 
 9     public static void main(String[] args) {
10         WeatherData data = new WeatherData(25.0F, 0.46F, 1.1F);//天气数据
11         Subject sj =  new WeatherForecast(data);//主题对象天气站
12         CurrentWeatherDisplay cw = new CurrentWeatherDisplay();//目前天气观察者,显示板块
13         FeatureWeather fw = new FeatureWeather();//未来天气板块
14         cw.register(sj);//注册
15         fw.register(sj);
16         sj.notifyAllObserver();//通知
17         data.setState(30.0F, 0.58F, 1.3F);//主题状态改变
18         ((WeatherForecast) sj).setWeatherData(data);//数据发生改变
19 
20         
21 
22     }
23 
24 }

 

11.测试结果截

面向对象设计模式之一观察者模式_第1张图片

12.设计模式在使用框架时候很方便,当然也可以使用模式自己开发框架

你可能感兴趣的:(面向对象设计模式之一观察者模式)