zoukankan      html  css  js  c++  java
  • 面向对象设计模式之一观察者模式

    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<Observer> observers;//所有注册的观察者
    12     private WeatherData data;//状态的引用
    13     
    14     
    15     public WeatherForecast( WeatherData data) {
    16         super();
    17         this.observers = new ArrayList<Observer>();
    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.测试结果截

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

  • 相关阅读:
    mybatis之关联关系映射
    spa项目开发之tab页实现
    mybatis整合redis实现二级缓存
    mybatis整合spring
    mybatis动态sql和分页
    Mybatis入门
    使用java代码操作redis
    Redis安装
    IDEA的安装和使用
    Linux入门——安装jdk、tomcat、MySQL以及项目部署
  • 原文地址:https://www.cnblogs.com/huipengbo/p/6868369.html
Copyright © 2011-2022 走看看