大家好,我是北军。本文介绍异步非阻塞框架是如何实现的。1.什么是观察者模式?定义对象之间的一对多依赖关系,这样当一个对象改变状态时,它的所有依赖关系都会被通知并自动更新。观察者模式(ObserverDesignPattern):定义对象之间一对多的依赖关系,当一个对象状态改变时,所有依赖的对象都会得到通知并自动更新。用人的话来说:也叫发布-订阅模式,可以解耦一个对象的变化,自动改变另一个对象的情况。2.观察者模式定义①Subject被观察对象定义了被观察对象必须实现的职责,必须能够动态添加和取消观察者。一般是抽象类或实现类,只完成作为被观察者必须实现的职责:管理观察者,通知观察者。②ObserverObserver观察者收到消息后,进行更新(update方法)操作,对接收到的信息进行处理。③ConcreteSubject具体的观察者定义了观察者自己的业务逻辑,同时定义了通知哪些事件。④ConcreteObserver具体的观察者在收到消息后有不同的处理反应,每个观察者都有自己的处理逻辑。3.观察者模式通用代码/***Observer*/publicinterfaceObserver{//更新方法voidupdate();}/***具体观察者*/publicclassConcreteObserverimplementsObserver{@Overridepublicvoidupdate(){System.out.println("接收信息并处理");}}/***Observer*/publicabstractclassSubject{//定义一个观察者数组privateListobsList=newArrayList<>();//添加一个观察者publicvoidaddObserver(Observerobserver){obsList.add(observer);}//删除一个观察者publicvoiddelObserver(Observerobserver){obsList.remove(observer);}//通知所有观察者publicvoidnotifyObservers(){for(Observerobserver:obsList){observer.update();}}}/***具体观察者*/publicclassConcreteSubjectextendsSubject{//具体业务publicvoiddoSomething(){super.notifyObservers();}}publicclassObserverClient{publicstaticvoidmain(String[]args){//创建一个观察者ConcreteSubjectsubject=newConcreteSubject();//定义一个观察者Observerobserver=newConcreteObserver();//观察者观察被观察者subject.addObserver(observer);subject.doSomething();}}4。JDK是在JDK的java中实现的。在util包下,为我们提供了观察者模式的抽象实现。如果你有兴趣,你可以看看。内部逻辑其实和我们上面介绍的观察者java.util.Observer类似。可观察的java.util.Observable。5、实例用户注册。注册完成后,将发送一封欢迎邮件。5.1公共实现publicclassUserController{publicvoidregister(StringuserName,StringpassWord){//1.根据用户名和密码存入数据库LonguserId=saveUser(userName,passWord);//2.如果上一步有结果则发送一封欢迎邮件if(userId!=null){Mail.sendEmail(userId);}}publicLongsaveUser(StringuserName,StringpassWord){return1L;}}上面的注册接口实现了两个东西,注册和发送Email,显然违反了单一职责原则,但是假设注册需求经常变化,这样写是没有问题的,但是如果需求变化了,比如不既发邮件又发短信,那么这样写,注册界面就复杂了。应该如何简化?没错,就是观察者模式。5.2观察者模式实现我们直接套用JDK的实现。importjava.util.Observable;/***用户登录-Observable*/publicclassUserControllerObservableextendsObservable{publicvoidregister(StringuserName,StringpassWord){//1.将用户名和密码保存到数据库中LonguserId=保存用户(用户名,密码);//2.如果上一步有结果,通知所有观察者if(userId!=null){super.setChanged();super.notifyObservers(用户名);}}publicLongsaveUser(StringuserName,StringpassWord){return1L;}}importjava.util.Observable;importjava.util.Observer;/***Sendmail-Observer*/publicclassMailObserverimplementsObserver{@Overridepublicvoidupdate(Observableo,Objectarg){System.out.println("发送邮件:"+arg+"欢迎");}}/***SendSMS-Observer*/publicclassSMSObserverimplementsObserver{@Overridepublicvoidupdate(Observableo,Objectarg){System.out.println("SendSMS:"+arg+"Welcome");}}测试:publicclassUserClient{publicstaticvoidmain(String[]args){UserControllerObservableobservable=newUserControllerObservable();observable.addObserver(newMailObserver());observable.addObserver(新的SMSObserver());observable.register("张三","123");}}通过observer模式改写后,后面会进行用户注册。即使我们添加其他操作,我们只需要添加一个观察者,注册接口register是不会改变的。5.3异步模式优化回到上图:注册后两步操作:发送邮件和发送短信。我们通过观察者模式重写上面之后,虽然流程很清晰,但是我们发现是顺序执行的,但是实际上这两个步骤并不是按顺序执行的,所以我们可以将其改为异步模式来提高执行效率。/***发送邮件-Observer*/publicclassMailObserverimplementsObserver{privateExecutorexecutor=Executors.newFixedThreadPool(2);@Overridepublicvoidupdate(Observableo,Objectarg){executor.execute(newRunnable(){@Overridepublicvoidrun(){System.out.println("发送邮件:"+arg+"欢迎");}});}}5.EventBus译为“事件总线”,它提供了实现观察orc模式的骨架代码。基于这个框架,我们可以很方便的在自己的业务场景中实现观察者模式,而无需从头开发。其中,GoogleGuavaEventBus是一个知名的EventBus框架,它不仅支持异步非阻塞模式,还支持同步阻塞模式。PS:GoogleGuava是一个特别好用的工具包,里面的代码也实现的比较优雅。有兴趣的可以研究下源码。https://github.com/google/guava下面我们用上面的例子来说明如何使用EventBus:①Guavapackagecom.google.guavaguava30.1.1-jre②具体代码如下:importcom.google.common.eventbus.AsyncEventBus;importcom.google.common.eventbus.EventBus;importjava.util.List;importjava.util.concurrent.Executors;publicclassUserController{privateEventBuseventBus;publicUserController(){eventBus=newAsyncEventBus(Executors.newFixedThreadPool(2));}/***注意:泛型参数是对象,不是接口观察者*@paramobserverList*/publicvoidsetObserverList(List