【设计模式-观察者模式(手动实现)】

系列文章目录

[0]设计模式-设计原则

[1]设计模式-策略模式

[2]设计模式-观察者模式(手动实现)

[3]设计模式-观察者模式(内置模型)

[4]设计模式-观察者模式(JFrame)

[5]设计模式-装饰者模式(初学缺陷版)

[6]设计模式-装饰者模式(进阶完善版)



前言

随着业务的复杂以及扩展,当我们需要某一个动作创建后,其他订阅的单元都能收到这个信息,那么观测者模式就能很好的解决这个问题。


一、观察者模式是什么?

定义了对象之间的一对多依赖,这样一来,当一个对象改变状态的时候,它的所有依赖者都会收到通知并自动更新。

二、核心代码

1.创建数据中心主题

代码如下(示例):提供一个subject,可以对订阅者发布数据,管理订阅者。代码延续上一遍,我打算用一个融合的代码贯通所有设计模式。

/**
 * 数据中心主题.<br>
 * 
 * <p>
 * 对订阅者的注册,移除,通知
 * <P>
 * 
 * @author likang5 <br>
 * @version 1.0.0 2022年5月17日<br>
 * @see
 * @since JDK 1.5.0
 */
public interface IDataCenterSubject {

	void registObserver(IDataCenterObserver o);

	void removeObserver(IDataCenterObserver o);

	void notifyObserver();

}

2.创建数据中心观察者

代码如下(示例):创建观察者接口,主要的思路是我们要接收数据中心推来的哪些数据来进行定义,观察者可以有很多,代码往下阅读。

/**
 * 数据中心观察者.<br>
 * 
 * @author likang5 <br>
 * @version 1.0.0 2022年5月17日<br>
 * @see
 * @since JDK 1.5.0
 */
public interface IDataCenterObserver {

	/**
	 * 接收主题推送来的数据.
	 * 
	 * @param dataHandler
	 */
	void recieveRobot(Robot r);
}

3.实现数据中心

代码如下(示例):数据中心的功能实现,除了实现主题接口的基本功能,还有接收最新的机器人数据,并发送给每个各个地区订阅了的数据中心主题的数据中心。

/**
 * 数据中心实现.<br>
 * 
 * @author likang5 <br>
 * @version 1.0.0 2022年5月17日<br>
 * @see
 * @since JDK 1.5.0
 */
public class DataCenter implements IDataCenterSubject {

	/**
	 * 观察者集合.
	 */
	private ArrayList<IDataCenterObserver> observers;

	/**
	 * 机器人数据.
	 */
	private Robot r;

	public DataCenter() {
		observers = new ArrayList<IDataCenterObserver>();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.study.designMode.observerMode.IDataCenterSubject#registObserver(com.study.designMode.observerMode.IDataCenterObserver)
	 */
	@Override
	public void registObserver(IDataCenterObserver o) {
		observers.add(o);

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.study.designMode.observerMode.IDataCenterSubject#removeObserver(com.study.designMode.observerMode.IDataCenterObserver)
	 */
	@Override
	public void removeObserver(IDataCenterObserver o) {
		int index = observers.indexOf(o);
		if (index >= 0) {
			observers.remove(o);
		}

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.study.designMode.observerMode.IDataCenterSubject#notifyObserver()
	 */
	@Override
	public void notifyObserver() {
		for (int i = 0; i < observers.size(); i++) {
			IDataCenterObserver observer = observers.get(i);
			observer.recieveRobot(r);

		}

	}

	public void dataCenterChanged() {
		notifyObserver();
	}

	public void publishRobot(Robot r) {
		this.r = r;
		dataCenterChanged();
	}

}

4.创建多个数据中心

代码如下(示例):当发现多个数据中心除了订阅主题,接收主题消息之外,还需要进行数据展示 。于是抽出一个接口做数据处理。

/**
 * 华北数据中心.<br>
 * 
 * @author likang5 <br>
 * @version 1.0.0 2022年5月17日<br>
 * @see
 * @since JDK 1.5.0
 */
public class DataCenterNorthChina implements IDataHandler, IDataCenterObserver {

	/**
	 * 数据主题.
	 */
	private IDataCenterSubject dataCenter;

	/**
	 * 接收最新发布的机器人.
	 */
	private Robot r;

	/**
	 * 初始化订阅数据中心.
	 * 
	 * @param dataCenter
	 */
	public DataCenterNorthChina(IDataCenterSubject dataCenter) {
		this.setDataCenter(dataCenter);
		dataCenter.registObserver(this);

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.study.designMode.observerMode.IDataCenterObserver#active(com.study.designMode.observerMode.IDataHandler)
	 */
	@Override
	public void recieveRobot(Robot r) {
		this.r = r;
		display();

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.study.designMode.observerMode.IDataHandler#run()
	 */
	@Override
	public void display() {
		System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");
		System.out.println("华南展示最新机器人\n" + r.getName());
		r.getPowerConsumptionMode().myMethod();
		System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");

	}

	/**
	 * 获取dataCenter.
	 * 
	 * @return the dataCenter
	 */
	public IDataCenterSubject getDataCenter() {
		return dataCenter;
	}

	/**
	 * 设置dataCenter.
	 * 
	 * @param dataCenter
	 *            the dataCenter to set
	 */
	public void setDataCenter(IDataCenterSubject dataCenter) {
		this.dataCenter = dataCenter;
	}

}
/**
 * 华南数据中心.<br>
 * 
 * @author likang5 <br>
 * @version 1.0.0 2022年5月17日<br>
 * @see
 * @since JDK 1.5.0
 */
public class DataCenterSouthChina implements IDataHandler, IDataCenterObserver {

	/**
	 * 数据中心Subject.
	 */
	private IDataCenterSubject dataCenter;

	/**
	 * 接收最新发布的机器人.
	 */
	private Robot r;

	/**
	 * 初始化订阅数据中心.
	 * 
	 * @param dataCenter
	 */
	public DataCenterSouthChina(IDataCenterSubject dataCenter) {

		this.setDataCenter(dataCenter);

		dataCenter.registObserver(this);

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.study.designMode.observerMode.IDataCenterObserver#active(com.study.designMode.observerMode.IDataHandler)
	 */
	@Override
	public void recieveRobot(Robot r) {
		this.r = r;
		display();

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.study.designMode.observerMode.IDataHandler#run()
	 */
	@Override
	public void display() {
		System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");
		System.out.println("华北展示最新机器人\n" + r.getName());
		r.getPowerConsumptionMode().myMethod();
		System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");
	}

	/**
	 * 获取dataCenter.
	 * 
	 * @return the dataCenter
	 */
	public IDataCenterSubject getDataCenter() {
		return dataCenter;
	}

	/**
	 * 设置dataCenter.
	 * 
	 * @param dataCenter
	 *            the dataCenter to set
	 */
	public void setDataCenter(IDataCenterSubject dataCenter) {
		this.dataCenter = dataCenter;
	}

}

5.创建数据处理接口

代码如下(示例):接收主题消息之外,还需要进行数据展示 。于是抽出一个接口做数据处理。也可以集成更多的数据处理功能,比如不同地区可以浮动价格之类。

/**
 * 数据处理.<br>
 * 
 * @author likang5 <br>
 * @version 1.0.0 2022年5月17日<br>
 * @see
 * @since JDK 1.5.0
 */
@FunctionalInterface
public interface IDataHandler {

	public void display();

}

6.创建测试类

代码如下(示例):简单的观察者模型就建立完成了,先测试一个数据中心订阅的结果。

/**
 * 观察者模式测试.<br>
 * 
 * @author likang5 <br>
 * @version 1.0.0 2022年5月17日<br>
 * @see
 * @since JDK 1.5.0
 */
public class ObserverTest {

	public static void main(String[] args) {

		// 创建数据中心
		DataCenter dataCenter = new DataCenter();

		// 订阅数据中心
		new DataCenterSouthChina(dataCenter);
		// new DataCenterNorthChina(dataCenter);

		// 生产机器人
		Robot r1 = new Robot();
		r1.setName("我是机器人一号 !");
		r1.setPowerConsumptionMode(new LowPowerConsumptionMode());

		// 数据中心发布机器人
		dataCenter.publishRobot(r1);

		// 生产机器人
		// Robot r2 = new Robot();
		// r2.setName("我是机器人二号 !");
		// r2.setPowerConsumptionMode(new HightPowerConsumptionMode());
		//
		// dataCenter.publishRobot(r2);

	}

}

在这里插入图片描述

代码如下(示例):发布两个机器人,代码上面都有,直接贴图。

在这里插入图片描述
在这里插入图片描述

代码如下(示例):有两个数据中心订阅了主题,发布两个机器人。

在这里插入图片描述


总结

以上就是对观察者模式的简单应用,了解的同学可能知道java工具提供了对应的模式,当前是手写的subject,手写的更加灵活。下一篇也会发布一个短篇,是使用工具来进行实现的,有兴趣的可以看一下。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值