zoukankan      html  css  js  c++  java
  • JAVA设计模式学习笔记-观察者模式

    观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化

    生活中的例子就是:订报纸、顶牛奶

    案例一:气象站
    一个普通的方案:

    气象站类

    package com.java.test.internetweather;
    
    import java.util.Observable;
    
    
    public class WeatherData extends Observable {
    	//气象站的信息
        //温度气压湿度
    	private float mTemperatrue;
    	private float mPressure;
    	private float mHumidity;
    
        //外部接入的类
        //公告板类
        //需要获得气象站的这些信息,并且气象站的信息变化,也要跟着变
    	private CurrentConditions mCurrentConditions;
    
        //有参构造,需要传入公告板类
    	public WeatherData(CurrentConditions mCurrentConditions)
    	{
    		this. mCurrentConditions= mCurrentConditions;
    	}
    	
        //三个get方法
    	public float getTemperature()
    	{
    		return mTemperatrue;	
    	}
    	public float getPressure()
    	{
    		return mPressure;
    		
    	}
    	public float getHumidity()
    	{
    		return mHumidity;
    
        //处理数据变化,数据变化,也要把变化的数据传入公告板类,实现跟着变
    	}
    	public void dataChange()
    	{
    		mCurrentConditions.update(this.getTemperature(),this.getPressure(),this.getHumidity());
    	}
    	
        //设定数据
    	public void setData(float mTemperature,float mPressure,float mHumidity)
    	{
    		this.mTemperatrue=mTemperature;
    		this.mPressure=mPressure;
    		this.mHumidity=mHumidity;
    		dataChange();
    	}
    }
    
    //公告板类
    ```java
    package com.java.test.internetweather;
    
    
    public class CurrentConditions {
    
    	//定义温度气压湿度
    	private float mTemperature;
    	private float mPressure;
    	private float mHumidity;
    
    	//设定三个参数
    	public void update(float mTemperature,float mPressure,float mHumidity)
    	{
    		this.mTemperature=mTemperature;
    		this.mPressure=mPressure;
    		this.mHumidity=mHumidity;
    		display();
    	}
    
    	//展示数据,在控制台模拟
    	public void display()
    	{
    		System.out.println("***Today mTemperature: "+mTemperature+"***");
    		System.out.println("***Today mPressure: "+mPressure+"***");
    		System.out.println("***Today mHumidity: "+mHumidity+"***");
    	}
    }
    
    //测试类
    ```java
    package com.java.test.internetweather;
    
    public class InternetWeather {
    
    	public static void main(String[] args) {
    		CurrentConditions mCurrentConditions;
    		WeatherData mWeatherData;
    		
    		mCurrentConditions=new CurrentConditions();
    		mWeatherData=new WeatherData(mCurrentConditions);
    		
    		mWeatherData.setData(30, 150, 40);
    	}
    }
    

    这种方式耦合性还是太高

    观察者模式设计方案

    Subject接口类

    package com.java.test.internetweather.observer;
    
    public interface Subject {
    	public void registerObserver(Observer o);
    	public void removeObserver(Observer o);
    	public void notifyObservers();
    }
    

    Observer

    package com.java.test.internetweather.observer;
    
    public interface Observer {
    	public void update(float mTemperatrue,float mPressure,float mHumidity);
    }
    

    公告牌一
    CurrentConditions

    package com.java.test.internetweather.mode;
    
    import com.java.test.internetweather.observer.Observer;
    
    public class CurrentConditions implements Observer {
    
    	/*私有变量*/
    	private float mTemperatrue;
    	private float mPressure;
    	private float mHumidity;
    
    	@Override
    	public void update(float mTemperatrue, float mPressure, float mHumidity) {
    		// TODO Auto-generated method stub
    		this.mHumidity = mHumidity;
    		this.mPressure = mPressure;
    		this.mTemperatrue = mTemperatrue;
    		display();
    	}
    
    	public void display() {
    		System.out.println("***Today mTemperatrue:" + mTemperatrue + "***");
    		System.out.println("***Today mPressure:" + mPressure + "***");
    		System.out.println("***Today mHumidity:" + mHumidity + "***");
    	}
    }
    

    公告牌二
    ForcastConditions

    package com.java.test.internetweather.mode;
    
    import com.java.test.internetweather.observer.Observer;
    
    
    public class ForcastConditions implements Observer{
    	private float mTemperatrue;
    	private float mPressure;
    	private float mHumidity;
    	@Override
    	public void update(float mTemperatrue, float mPressure, float mHumidity) {
    		// TODO Auto-generated method stub
    		this.mTemperatrue=mTemperatrue;
    		this.mPressure=mPressure;
    		this.mHumidity=mHumidity;
    		
    		display();
    	}
    	public void display()
    	{
    		System.out.println("**明天温度:"+(mTemperatrue+Math.random())+"**");
    		System.out.println("**明天气压:"+(mPressure+10*Math.random())+"**");
    		System.out.println("**明天湿度:"+(mHumidity+Math.random())+"**");
    	}
    }
    

    测试类
    InternetWeather

    package com.java.test.internetweather.mode;
    
    
    
    public class InternetWeather {
    
    	public static void main(String[] args) {
    		
    		CurrentConditions mCurrentConditions;
    		ForcastConditions mForcastConditions;
    		WeatherDataSt mWeatherDataSt;
    		
    		mWeatherDataSt=new WeatherDataSt();
    		mCurrentConditions=new CurrentConditions();
    		mForcastConditions=new ForcastConditions();
    		
    		mWeatherDataSt.registerObserver(mCurrentConditions);
    		mWeatherDataSt.registerObserver(mForcastConditions);
    		
    		mWeatherDataSt.setData(30, 150, 40);
    		mWeatherDataSt.removeObserver(mCurrentConditions);
    		mWeatherDataSt.setData(40, 250, 50);
    	}
    }
    

    观察者模式实现了比较好的低耦合特性,Object和Observer之间的关系只有实现了update方法这一关系,耦合性非常低

    Java内置了观察者对象
    Observable
    Observer

    Subject

    WeatherData

    package com.java.test.internetweather.jv;
    
    import java.util.Observable;
    
    public class WeatherData extends Observable{
    	private float mTemperatrue;
    	private float mPressure;
    	private float mHumidity;
    	
    	public float getTemperature()
    	{
    		return mTemperatrue;
    		
    	}
    	
    	public float getPressure()
    	{
    		return mPressure;
    		
    	}
    	
    	public float getHumidity()
    	{
    		return mHumidity;
    		
    	}
    	
    	
    	public void dataChange()
    	{
    		//表示数据变化了
    		//从源码中可以看到里面有个bool值变为了true,下面那个方法会判断这个是否为true
    		this.setChanged();
    		//这个方式是等观察者自己拉取
    		//this.notifyObservers();
    		//这个方式是把信息主动推送给观察者
    		this.notifyObservers(new Data(getTemperature(),getPressure(),getHumidity()));
    		
    	}
    	
    	
    	public void setData(float mTemperatrue,float mPressure,float mHumidity)
    	{
    		this.mTemperatrue=mTemperatrue;
    		this.mPressure=mPressure;
    		this.mHumidity=mHumidity;
    		dataChange();
    	}
    	
    	public class Data
    	{
    		public float mTemperatrue;
    		public float mPressure;
    		public float mHumidity;
    		public Data(float mTemperatrue,float mPressure,float mHumidity)
    		{
    			this.mTemperatrue=mTemperatrue;
    			this.mPressure=mPressure;
    			this.mHumidity=mHumidity;
    		}
    	}	
    }
    

    公告板一

    package com.java.test.internetweather.jv;
    
    import java.util.Observable;
    import java.util.Observer;
    
    import com.java.test.internetweather.jv.WeatherData.Data;
    
    
    public class CurrentConditions implements Observer {
    	
    	private float mTemperatrue;
    	private float mPressure;
    	private float mHumidity;
    
    	@Override
    	public void update(Observable arg0, Object arg1) {
    		// TODO Auto-generated method stub
    		this.mTemperatrue=((Data)(arg1)).mTemperatrue;
    		this.mPressure=((Data)(arg1)).mPressure;
    		this.mHumidity=((Data)(arg1)).mHumidity;
    		display();
    	}
    	
    	public void display()
    	{
    		System.out.println("***Today mTemperatrue:" +mTemperatrue+"***");
    		System.out.println("***Today mPressure:" +mPressure+"***");
    		System.out.println("***Today mHumidity:" +mHumidity+"***");
    	}
    	
    	
    }
    
    

    公告板二
    ForcastConditions

    package com.java.test.internetweather.mode;
    
    import com.java.test.internetweather.observer.Observer;
    
    
    public class ForcastConditions implements Observer{
    	private float mTemperatrue;
    	private float mPressure;
    	private float mHumidity;
    	@Override
    	public void update(float mTemperatrue, float mPressure, float mHumidity) {
    		// TODO Auto-generated method stub
    		this.mTemperatrue=mTemperatrue;
    		this.mPressure=mPressure;
    		this.mHumidity=mHumidity;
    		
    		display();
    	}
    	public void display()
    	{
    		System.out.println("**明天温度:"+(mTemperatrue+Math.random())+"**");
    		System.out.println("**明天气压:"+(mPressure+10*Math.random())+"**");
    		System.out.println("**明天湿度:"+(mHumidity+Math.random())+"**");
    	}
    }
    

    测试类

    package com.java.test.internetweather.jv;
    
    public class InternetWeather {
    	public static void main(String[] args) {
    		CurrentConditions mCurrentConditions;
    		ForcastConditions mForcastConditions;
    		WeatherData mWeatherData;
    		 
    		mCurrentConditions=new CurrentConditions();
    		mForcastConditions=new ForcastConditions();
    		mWeatherData=new WeatherData();
    		
    		mWeatherData.addObserver(mCurrentConditions);
    		mWeatherData.addObserver(mForcastConditions);
    		mWeatherData.setData(30, 150, 40);
    		
    		mWeatherData.deleteObserver(mCurrentConditions);
    		mWeatherData.setData(35, 150, 60);
    		
    	}
    }
    
  • 相关阅读:
    iOS通知的使用
    使用代理和block写一个alertView
    MongoDB的访问权限和用户设置
    编写高效SQL语句
    Linux 安装 jdk 环境
    基于3dsMax的地图编辑器设想
    入驻cnBlogs!
    毕设开发总结3D游戏框架及网络对战游戏的开发(1)
    gkENGINE 个人图形引擎展示
    利用D3DQUERY实现简单的GPU计时器
  • 原文地址:https://www.cnblogs.com/kristse/p/observer.html
Copyright © 2011-2022 走看看