JAVA观察者模式(买彩票案例)

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

源码地址:https://gitee.com/yang-kairui/design-pattern
JAVA的JDK和很多框架都用到了观察者模式,最典型的比如说spring mvc中的DispatcherServelet以及Zookeeper的动态监控注册中心,感兴趣的话可以去阅读一下源码
在这里插入图片描述
如上图所示,服务号就是我们的主题,使用者就是观察者。现在我们明确下功能:

1、服务号就是主题,业务就是推送消息

2、观察者只需要订阅主题,只要有新的消息就会送来

3、当不想要此主题消息时,取消订阅

4、只要服务号还在,就会一直有人订阅

好了,现在我们来看看观察者模式的类图:
在这里插入图片描述

接下来就是代码时间了,我们模拟一个买彩票的场景,彩票站就是主题,买彩票的人就是观察者。

首先定义两个接口,主题接口Subject、订阅者接口Observer

/**
 * 所有的被观察主题需要实现该接口
 *
 * @author ykr
 * @date 2022/3/31
 */
public interface Subject {

	/**
	 * 存储所有观察者
	 * @return List<Observer>
	 */
	List<Observer> getObservers();

	/**
	 * 注册一个观察者
	 * @param observer 订阅的观察者对象
	 */
	void registerObserver(Observer observer);

	/**
	 * 移除一个观察者
	 * @param observer 订阅的观察者对象
	 */
	void removeObserver(Observer observer);

	/**
	 * 通知所有观察者
	 */
	void notifyObservers();
}
/**
 * 所有订阅者需要实现该接口
 *
 * @author ykr
 * @date 2022/3/31
 */
public interface Observer {
	void update(String msg);
}

接下来实现一个彩票主题LotterySubject 和彩民订阅者LotteryHolders

/**
 * 彩票主题
 *
 * @author ykr
 * @date 2022/3/31
 */
public class LotterySubject implements Subject {

	/**
	 * 所有买彩票的彩民
	 */
	private List<Observer> observers = new ArrayList<>();

	/**
	 * 开奖号码
	 */
	private String msg;

	@Override
	public List<Observer> getObservers() {
		return this.observers;
	}

	@Override
	public void registerObserver(Observer observer) {
		observers.add(observer);
	}

	@Override
	public void removeObserver(Observer observer) {
		int index = observers.indexOf(observer);
		if (index >= 0) {
			observers.remove(observer);
		}
	}

	@Override
	public void notifyObservers() {
		for (Observer observer : observers) {
			observer.update(msg);
		}
	}

	/**
	 * 开奖
	 */
	public void lottery(String msg) {
		this.msg = msg;
		notifyObservers();
	}
}
/**
 * 持有彩票的人
 *
 * @author ykr
 * @date 2022/3/31
 */
public class LotteryHolders implements Observer {

	private String lottery;

	LotteryHolders(String lottery) {
		this.lottery = lottery;
	}

	@Override
	public void update(String msg) {
		//开奖
		System.out.println("本期开奖号码:" + msg + ",我的号码:" + lottery);
	}
}

最后模拟买彩票案例LotteryTest

/**
 * 买彩票模拟
 *
 * @author ykr
 * @date 2022/3/31
 */
public class LotteryTest {
	public static void main(String[] args) {
		LotteryHolders li = new LotteryHolders(String.valueOf(new Random().nextInt(10)));
		LotteryHolders wang = new LotteryHolders(String.valueOf(new Random().nextInt(10)));
		LotteryHolders yang = new LotteryHolders(String.valueOf(new Random().nextInt(10)));
		LotterySubject lotteryStore = new LotterySubject();
		lotteryStore.registerObserver(li);
		lotteryStore.registerObserver(wang);
		lotteryStore.registerObserver(yang);
		lotteryStore.lottery("5");
	}
}

执行结果

本期开奖号码:5,我的号码:4 本期开奖号码:5,我的号码:9 本期开奖号码:5,我的号码:7

23种设计模式JAVA案例

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值