龙空技术网

设计模式-观察者模式 发布/订阅模式

mySoul2018 159

前言:

眼前咱们对“js订阅者模式和观察者模式代码”大概比较注重,你们都想要学习一些“js订阅者模式和观察者模式代码”的相关内容。那么小编同时在网络上收集了一些有关“js订阅者模式和观察者模式代码””的相关内容,希望朋友们能喜欢,朋友们一起来了解一下吧!

设计模式-观察者模式 发布/订阅模式

代码

观察者接口

public interface IHanFeiZi{	// 当吃早饭时	public void havBreakFast();	// 进行娱乐活动时	public void haveFun();}

具体的被观察者

public class HanFeiZi implements IHanFeiZi{	`// 根据是否在吃饭,作为监控的标准	private boolean isHavingBreakfast = false;	// 判断是否在娱乐	private boolean isHavingFun = false;	// 当吃饭的时候	public void haveBreakfast(){		System.out.println("吃饭了");		this.isHavingBreakfast = true;	}	// 当开始娱乐的时候	public void haveFun(){		System.out.println("开始娱乐");		this.isHavingFun = true;	}	// 下方位get/set省去}

观察者

public interface ILiSi{	// 发行有人有动静,进行行动	public void update(String context);}public class LiSi implements ILiSi{	// 首先他为一个观察者	public void update(String str){		System.out.println("观察到某人活动,进行汇报");		this.reportToQinShiHuang(str);	// 调用汇报方法		System.out.println("汇报完毕");	}	// 进行汇报、	private void reportToQinShiHuang(String reportContext){		System.out.println("进行汇报");	}}

最后定义中间

class Spy extends Thread{	private HanFeiZi hanFeiZi;	private LiSi liSi;	private String type;	// 通过构造函数注入,显示将要监控谁	public Spy(HanFeiZi _hanFeiZi, LiSi _liSi, String _type){		this.hanFeiZi = _hanFeiZi;		this.liSi = _liSi;		this.type = _type;	}	@Override	public void run(){		while(true){			if(this.type.equals("breakfast")){	// 监控是否吃早餐				// 如果在吃饭,则通知				if(this.hanFeiZi.isHavingBreakfast()){					this.liSi.update("在吃饭");					// 重置状态,继续监控					this.hanFeiZi.setHavingBreakfast(false);				}			}else{	// 判断是否在娱乐				if(this.hanFeiZi.isHavingFun()){					this.liSi.update("在娱乐");					this.hanFeiZi.setHavingFun(false);				}			}		}	}}

场景类

public class Client{	public static void main(String[] args) throws interruptedException {		// 定义两个人		LiSi liSi = new LiSi();		HanFeiZi hanFeiZi = new HanFeiZi();		// 观察早餐		Spy watchBreakfast = new Spy(hanFeiZi, lisi, "breakfast");		watchBreak.start();	// 启动线程、		// 继续查看都干什么		Thread.sleep(1000);		hanFeiZi.haveBreakfast();	// 开始吃饭		// 如果娱乐		Thread.sleep(1000);		hanFeiZi.haveFun();	// 查看情况	}}
修改

由于上面使用了一个死循环,会导致出现问题。并且由于多线程的缘故,会导致数据的污染问题,根本无法使用。

修改如下

public class HanFeiZi implements IHanFeiZi{	// 声明李	private ILiSi lisi = new LiSi();	// 当吃饭的时候	public void hanveBreakfast(){		System.out.println("吃饭开始");		this.liSi.update("吃饭了");	}	// 当娱乐的时候	public void haveFun(){		System.out.println("开始娱乐");		this.liSi.update("在娱乐");	}}

最后书写场景类

public class Client{	public static void main(String[] args){		// 定义出韩		HanFeiZi hanFeiZi = new HanFeiZi();		// 继续查看韩在干什么		hanFeiZi.haveBreakfast();		// 当其娱乐		hanFeiZi.haveFun();	}}
继续改进

如果这样聚合,如果有一堆人需要监控被观察者,这样不行,不能一个监控一个,如果此时要修改其他的监控内容,那么都要修改,违反开闭原则

开闭原则 对扩展开放,对修改关闭

那么,将被观察者的自身活动定义一个接口,被观察者定义接口,在统一的类HanFeiZi中实现该接口,对于观察者来说,定义一个观察者的接口,然后多名观察者分别实现该类

被观察者

public interface Observable {	// 增加一个观察者	public void addObserver(Observer observer);	// 删除一个观察者	public void deleteObserver(Observer observer);	// 当发生动作的时候,通知观察者	public void notifyObservers(String context);}

上方是一个统一的观察者接口,所有的观察者都能实现这个接口。继续查看被观察者

public class HanFeiZi implements Observalbe, IHanFeiZi{	// 定义数组,用于保存观察者	private ArrayList observerList = new ArrayList();	// 增加观察者	public void addObserver(Observer observer){		this.observerList.add(observer);	}	// 删除观察者	public void deleteObserver(Observer observer){		this.observerList.remove(observer);	}	// 通知所有的观察者	public void notifyObservers(String context){		for(Observer observer:observerList){			observer.update(context);		}	}	// 当要吃饭了	public void haveBreakfast(){		System.out.println("吃饭");		// 通知观察者		this.notifyObservers("在吃饭");	}	// 开始娱乐	public void haveFun(){		System.out.println("开始娱乐");		this.notifyObservers("在娱乐");	}}// 书写观察者接口public interface Observer{	// 发现动静,进行行动	poublic void update(String context);}// 书写三个观察者,只需要实现观察者的接口即可public class LiSi implements Observer{	// 首先要为观察者	public void update(String str){		System.out.println("开始活动了");		// 汇报		this.reportToQinShiHuang(str);		System.out.println("汇报完毕");	}	// 汇报	private void reportToQinShiHuang(String reportContext){		System.out.println("进行汇报");	}}

同理,需要观察者直接实现接口即可。

场景类

public class Client{	public static void main(String[] args){		// 定义三个观察者		Observer liSi = new LiSi();		Observer wangSi = new WangSi();		Observer liuSi = new LiuSi();		// 定义被观察的		HanFeiZi hanFeiZi = new HanFeiZi();		// 当三个人观察韩的时候		hanFeiZi.addObserver(liSi);		hanFeiZi.addObserver(wangSi);		hanFeiZi.addObserver(liuSi);		// 然后查看在干什么		hanFeiZi.haveBreakfast();	}}

这样就完成了观察者模式,当被观察的发生改变的时候,通知被通过构造方法注入的观察者,此观察者保存在动态数组中,然后当被观察者发生改变的时候,只需要使用循环通知保存在数组中的观察者即可。

这里有一个接口,如果有多个观察者,可以定义一个接口,只需要实现这个即可即可,声明一个接口,然后使用不同的实例,对接口进行实例化。即可。

订阅/发布模型

观察者模式同时也叫发布订阅模型,即,消息驱动,消息发布着发布一个消息,然后通过容器实现对订阅者的进行发布,达到通知订阅者的目的,并且订阅者动态的保存在数组中。

标签: #js订阅者模式和观察者模式代码