设计模式-行为型-观察者模式-史上最通俗的方式让你明白

1.需求提出

1. 中央气象局需要设计一个系统,对外提供sdk接口,是的想百度、新浪、等等第三方的网站可以实时感知到中央气象局传感器实时(每5秒钟想中心系统回报一次温度、湿度信息)获取的温度、湿度等信息
2. 特别注意,这些接入的第三方不去定都有谁,谁想象如就可以接入,比如你自己开发一个网站想引流,你可以对接中央气象局的气象接口,为大众提供天气展示服务,再比如想在的墨迹天气等也是对接的类似这种中央气象台的借口。
3. 如果中央气象台天气情况发生变化的时候就(主动)通过推送的方式更新各接入第三方的天气信息。
4. 实现ocp原则,低内聚、高耦合的方案。

2.设计

这是一个典型的观察者模式的使用场景,可以使用观察者模式。
《设计模式-行为型-观察者模式-史上最通俗的方式让你明白》

这个URL图解释:

  1. Subject:就是中央气象局的父类,主要提供三个方法:注册、删除、发送通知
  2. WeatherData:是Subject类的实现类,是一个天气数据的demo类,含有温度、湿度、气压等信息。另外含有一个注册上来的第三方(观察者)的来表。同时含有推送消息的方法。
  3. Observer观察者的接口。想要接入中央气象平台,就必须实现这个接口,重写update方法,这个方法是平台天气变化后的通知各个第三方时调用的方法。
  4. 这里有个天大的好处就是,如果有N个第三方平台需要接入进来,我们平台的业务逻辑一毛钱都不需要该。你说爽不爽。
  5. 哈哈哈哈。超级爽。

3.设计之平台核心接口

3.1Subject.java接口

/** * 接口, 让WeatherData 来实现 */
public interface Subject { 
	public void registerObserver(Observer o); //注册第三方
	public void removeObserver(Observer o); //移除第三方
	public void notifyObservers(); //推送消息到所有的第三方
}

3.1WeatherData.java类,实现了Subject.java接口

import java.util.ArrayList;

/** * 类是核心 * 1. 包含最新的天气情况信息 * 2. 含有 观察者集合,使用ArrayList管理 * 3. 当数据有更新时,就主动的调用 ArrayList, 通知所有的(接入方)就看到最新的信息 * */
public class WeatherData implements Subject { 
	private float temperatrue;
	private float pressure;
	private float humidity;
	//观察者集合
	private ArrayList<Observer> observers;

	public WeatherData() { 
		observers = new ArrayList<Observer>();
	}

	public float getTemperature() { 
		return temperatrue;
	}

	public float getPressure() { 
		return pressure;
	}

	public float getHumidity() { 
		return humidity;
	}

	public void dataChange() { 
		//调用 接入方的 update
		notifyObservers();
	}

	//当数据有更新时,就调用平台的传感器调用这个方法,会发生联动效应同时推送到第三方
	public void setData(float temperature, float pressure, float humidity) { 
		this.temperatrue = temperature;
		this.pressure = pressure;
		this.humidity = humidity;
		//调用dataChange, 将最新的信息 推送给 接入方第三方
		dataChange();
	}

	//注册一个观察者
	@Override
	public void registerObserver(Observer o) { 
		observers.add(o);
	}

	//移除一个观察者
	@Override
	public void removeObserver(Observer o) { 
		// TODO Auto-generated method stub
		if(observers.contains(o)) { 
			observers.remove(o);
		}
	}

	//遍历所有的观察者,并通知
	@Override
	public void notifyObservers() { 
		// TODO Auto-generated method stub
		for(int i = 0; i < observers.size(); i++) { 
			observers.get(i).update(this.temperatrue, this.pressure, this.humidity);
		}
	}
}

4.设计之第三方使用的顶级接口

4.1Observer.java接口,所有第三方必须实现它

/** * 观察者接口,有观察者来实现 */

public interface Observer { 
	//第三方实现这个接口和重写这个方法,去更新自己的天气数据
	public void update(float temperature, float pressure, float humidity);
}

4.1百度平台天气预报第三方接入者

public class BaiduSite implements Observer { 

	// 温度,气压,湿度
	private float temperature;
	private float pressure;
	private float humidity;

	// 更新 天气情况,是由 WeatherData 来调用,我使用推送模式
	public void update(float temperature, float pressure, float humidity) { 
		this.temperature = temperature;
		this.pressure = pressure;
		this.humidity = humidity;
	}
}

4.2新浪平台天气预报第三方接入者


public class XinLangSite implements Observer { 

	// 温度,气压,湿度
	private float temperature;
	private float pressure;
	private float humidity;

	// 更新 天气情况,是由 WeatherData 来调用,我使用推送模式
	public void update(float temperature, float pressure, float humidity) { 
		this.temperature = temperature;
		this.pressure = pressure;
		this.humidity = humidity;
	}
}

4.3后面接入N个的写法也是一样的

public class NNNNNNN implements Observer { 

	// 温度,气压,湿度
	private float temperature;
	private float pressure;
	private float humidity;

	// 更新 天气情况,是由 WeatherData 来调用,我使用推送模式
	public void update(float temperature, float pressure, float humidity) { 
		this.temperature = temperature;
		this.pressure = pressure;
		this.humidity = humidity;
	}
}

5.其他问题交代

到此整个设计就完成了。那么有人会问,怎么注册,怎么移除这册呢?
其实这个很简单,

  1. 注册时可以在第三方接入平台的时候,发送报文,或者通过其他的对应接口把第三方的平台的数据存入到数据库,我们这里是存入list也是可以的。
  2. 移除注册时,可以是第三房平台自己想平台发送移除请求有平台进行移除,或者其他的一些校验策略对其进行移除。
  3. 此处不做client的manin方法的单元测试,因为越测试你越糊涂,这样最好。

6.总结

到此我们完整个平台的设计就完成了。是不是高内聚低耦合,完全做到了ocp呢!
平台岿然不动,第三方相接多少接多少。

    原文作者:前路无畏
    原文地址: https://blog.csdn.net/fsjwin/article/details/109321178
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞