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);
		
	}
}
posted @ 2020-02-02 13:57  KrisTse  阅读(164)  评论(0编辑  收藏  举报