觀察者模式(7)

案例

引入一個很常見的案例。現在有一家氣象站負責發佈氣象消息(WeatherData),作爲不同的客戶,會有不同的對於氣象消息的需求,我們也就需要設計一個或者多個面向用戶的消息面板獲取氣象總站的消息,並更新給用戶滿意的定製數據,用來獲取報酬。

Internet氣象站項目

  • 提供溫度、氣壓和溼度的接口
  • 測量數據更新時需時時通知給第三方
  • 需要設計開放型API,便於其他第三方公司也能接入氣象站獲取數據

用OOP思想,代碼如下:
1.服務提供方

@Data
public class WeatherData {

	private float mTemperature;
	private float mPressure;
	private float mHumidity;
	
	private CurrentConditions currentConditions;

	public WeatherData(CurrentConditions currentConditions) {
		this.currentConditions = currentConditions;
	}
	
	public void setData(float mTemperature, float mPressure, float mHumidity){
		this.mTemperature = mTemperature;
		this.mPressure = mPressure;
		this.mHumidity = mHumidity;
		setChange();
	}
	private void setChange() {
		currentConditions.setData(mTemperature, mPressure, mHumidity);
	}	
}

2.觀察者

@Data
public class CurrentConditions {
	private float mTemperature;
	private float mPressure;
	private float mHumidity;
	
	public void setData(float mTemperature,float mPressure,float mHumidity){
		this.mTemperature = mTemperature;
		this.mPressure = mPressure;
		this.mHumidity = mHumidity;
		display();
	}	
	public void display(){
		System.out.println("mTemperature ="+mTemperature);
		System.out.println("mPressure ="+mPressure);
		System.out.println("mHumidity ="+mHumidity);
	}
}

3.客戶端測試

public class Tests {
	public static void main(String[] args) {
		CurrentConditions cns = new CurrentConditions();
		WeatherData wd = new WeatherData(cns);
		wd.setData(12, 55, 88);
	}
}

有些問題
1)其他第三方公司接入氣象站獲取數據的問題
2)無法在運行時動態的添加第三方

觀察者模式: 對象之間多對一依賴的一種設計方案,被依賴的對象爲Subject,依賴的對象爲Observer,Subject通知Observer變化

代碼實現如下:

//服務提供方接口
public interface Subject {
	void register(Observer e);
	void remove(Observer e);
}
//觀察者接口基類
public interface Observer {
	void updateDatas(float mTemperature, float mPressure, float mHumidity);
}

服務端實現如下:

@Data
public class WeatherDataSt implements Subject{
	
	private float mTemperature;
	private float mPressure;
	private float mHumidity;
	
	private List<Observer> lists;
	public WeatherDataSt() {
		this.lists = new ArrayList<Observer>();
	}
	
	public void setData(float mTemperature, float mPressure, float mHumidity){
		this.mTemperature = mTemperature;
		this.mPressure = mPressure;
		this.mHumidity = mHumidity;	
		notifyAllObserver();
	}
	private void notifyAllObserver() {
		for(Observer item:lists){
			item.updateDatas(mTemperature, mPressure, mHumidity);
		}
	}
	@Override
	public void register(Observer e) {
		lists.add(e);
	}
	@Override
	public void remove(Observer e) {
		if(lists.contains(e)){
			lists.remove(e);
		}
	}
}

觀察者代碼實現

@Data
public class CurrentConditions implements Observer{

	private float mTemperature;
	private float mPressure;
	private float mHumidity;
	
	
	public void display(){
		System.out.println("CurrentConditions mTemperature ="+mTemperature);
		System.out.println("CurrentConditions mPressure ="+mPressure);
		System.out.println("CurrentConditions mHumidity ="+mHumidity);
	}

	@Override
	public void updateDatas(float mTemperature, float mPressure, float mHumidity) {
		this.mTemperature = mTemperature;
		this.mPressure = mPressure;
		this.mHumidity = mHumidity;
		display();
	}
}

@Data
public class FutureConditions implements Observer{

	private float mTemperature;
	private float mPressure;
	private float mHumidity;
	
	
	public void display(){
		System.out.println("FutureConditions mTemperature ="+mTemperature);
		System.out.println("FutureConditions mPressure ="+mPressure);
		System.out.println("FutureConditions mHumidity ="+mHumidity);
	}

	@Override
	public void updateDatas(float mTemperature, float mPressure, float mHumidity) {
		this.mTemperature = mTemperature;
		this.mPressure = mPressure;
		this.mHumidity = mHumidity;
		display();
	}
}

測試代碼:

public class Test {
	public static void main(String[] args) {
		Observer current = new CurrentConditions();
		Observer forcast = new FutureConditions();
		
		WeatherDataSt sj = new WeatherDataSt();
		sj.register(current);
		sj.register(forcast);
		
		sj.setData(22, 55, 88);
		System.out.println("----");
		sj.remove(current);
		sj.setData(229, 559, 889);
	}
}

Java內置觀察者

Java內置的觀察者
Observable 是類,需要被繼承
Observer

代碼實現
1.服務端代碼

public class WeatherDataSt extends Observable{
	
	private float mTemperature;
	private float mPressure;
	private float mHumidity;
	
	public void setData(float mTemperature,float mPressure,float mHumidity){
		this.mTemperature = mTemperature;
		this.mPressure = mPressure;
		this.mHumidity = mHumidity;
		
		notifyClient();
	}

	private void notifyClient() {
		this.setChanged();
		this.notifyObservers(new DataModule(mTemperature, mPressure, mHumidity));
	}
}

2.客戶端代碼

@Data
public class CurrentConditions implements Observer{

	private float mTemperature;
	private float mPressure;
	private float mHumidity;
		
	public void display(){
		System.out.println("CurrentConditions mTemperature ="+mTemperature);
		System.out.println("CurrentConditions mPressure ="+mPressure);
		System.out.println("CurrentConditions mHumidity ="+mHumidity);
	}	
	@Override
	public void update(Observable o, Object arg) {
		DataModule dm = (DataModule) arg;
		this.mTemperature = dm.mTemperature;
		this.mPressure = dm.mPressure;
		this.mHumidity = dm.mHumidity;
		display();
	}
}

@Data
public class FutureConditions implements Observer{

	private float mTemperature;
	private float mPressure;
	private float mHumidity;
	
	public void display(){
		System.out.println("FutureConditions mTemperature ="+mTemperature);
		System.out.println("FutureConditions mPressure ="+mPressure);
		System.out.println("FutureConditions mHumidity ="+mHumidity);
	}


	@Override
	public void update(Observable o, Object arg) {
		DataModule dm = (DataModule) arg;
		this.mTemperature = dm.mTemperature;
		this.mPressure = dm.mPressure;
		this.mHumidity = dm.mHumidity;
		display();
	}	
}

3.測試以及其他

@Data
public class DataModule {

	public float mTemperature;
	public float mPressure;
	public float mHumidity;
	
	public DataModule(float mTemperature, float mPressure, float mHumidity) {
		super();
		this.mTemperature = mTemperature;
		this.mPressure = mPressure;
		this.mHumidity = mHumidity;
	}
}

public class Test {
	public static void main(String[] args) {
		Observer current = new CurrentConditions();
		Observer forcast = new FutureConditions();
		
		WeatherDataSt sj = new WeatherDataSt();
		sj.addObserver(current);
		sj.addObserver(forcast);
		
		sj.setData(22, 55, 88);
		System.out.println("----");
		sj.deleteObserver(forcast);
		sj.setData(229, 559, 889);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章