消息队列(MQ),一种可以实现生产者到消费者单向通信的通信模型,也是现在常用的主流中间件。常见的有RabbitMQ、ActiveMQ、Kafka等,它们也有很多优点,比如解耦、异步、广播、削峰等。在设计模式中,还有一种模式可以有效的实现解耦和异步的特性,那就是观察者模式,也称为发布-订阅模式。今天阿兵就给大家分享一下这种在实际开发中比较常见的模式的轮廓。什么是观察者模式?它的目的是什么?当一个对象的状态发生变化时,其他注册的对象可以观察到这一变化,从而做出自己相应的变化。这样就达到了降低依赖和解耦的效果。举个例子,就像微信朋友圈,以当前个人为订阅者,以好友为主题。当一个人发布动态朋友圈时,他的朋友就可以看到这个朋友圈,并且可以自主选择点赞或者评论。感觉有点抽象,我们来看看它的主要作用:Subject:主要由一个类实现的可观察接口,通知观察者使用attach方法,detach方法取消观察。ConcreteSubject(具体主题):是实现主题接口的类,处理观察者中的变化Observe(观察者):观察者是一个以对象为界的接口,根据主题的变化进行更新。这种方式作用不多,但感觉还是有点抽象。让我们看一下具体的示例代码。我们以上面的朋友圈为例来看代码实现topic定义先定义增删关系并通知订阅者}@Overridepublicvoiddetach(Observerobserver){//解除订阅关系observers.remove(observer);}@OverridepublicvoidnotifyObservers(Stringmessage){//通知订阅者for(Observerobserver:observers){observer.update(message);}}}然后创建一个具体topic,构建容器维护订阅关系,支持增删关系,并通知订阅者publicinterfaceObserver{//处理业务逻辑voidupdate(Stringmessage);}创建观察者接口,方便我们管理publicclassFriendOneObserverimplementsObserver{@Overridepublicvoidupdate(Stringmessage){//模拟业务逻辑System.out.println("FriendOne知道thatyouhavepostedsomething"+message);}}最后创建具体的观察者类,实现观察者接口的update方法,处理自己的业务逻辑publicclasstest{publicstaticvoidmain(String[]args){ConcreteSubjectsubject=newConcreteSubject();//这里假设添加了一个好友朋友圈动态主题.notifyObservers("第一条朋友圈消息");//输出结果:FriendOne知道你发了第一条朋友圈//FriendTwo知道你发了第一条朋友圈//这里是发现twoObserver推荐卖茶,删除好友看看测试结果。通过ConcreteSubject维护订阅关系。通过notifyObservers方法通知订阅者后,观察者获取消息并处理自己的业务逻辑。这里细心的小伙伴已经达到了理解耦合的效果,同时减少了依赖,每个观察者不需要知道发布者处理什么业务逻辑,也不需要依赖发布者的任何业务模型,并且只关心它需要处理的逻辑。如果新增业务,我们只需要创建一个新的订阅者,维护在观察者容器中即可,这也符合我们的开闭原则。这只是一个同步实现,我们还可以扩展其他异步实现,或者使用多线程等实现。观察者模式在框架中的应用应该很多。第一个熟悉JDK的人应该知道java.util包中除了常用的collections和maps之外还有一个Observable类。它的实现方式其实就是观察模式。还有增删改查的方??法。这里需要注意的是,他使用的是Vector作为订阅关系的容器。同时,他在自己的定义方法中加入synchronized关键字修饰类,实现线程安全。这里贴出关键源码。有兴趣的同学可以自己打开看各个方法的评论。第二种在Spring中有一个ApplicationListener,也是用观察者模式处理的。以ApplicationEventMulticaster为主题,里面有增删改查,通知等。Spring有一些内置事件。当某个操作完成时,会发出某些事件动作。其处理方式也是上述方式。当然,里面还有很多。我没有详细说明。有兴趣的同学可以仔细了解一下Spring的启动过程。importjava.util.EventListener;/***应用事件监听器要实现的接口。*基于观察者设计模式的标准{@codejava.util.EventListener}接口*。观察者模式**importjava.util.EventListener;/***Interfacetobeimplementedbyapplicationeventlisteners.*Basedonthestandard{@codejava.util.EventListener}interface*fortheObserverdesignpattern.//这里也说明了采用观察者模式**
AsofSpring3.0,anApplicationListenercangenericallydeclaretheeventtype*thatitisinterestedin.WhenregisteredwithaSpringApplicationContext,events*willbefilteredaccordingly,withthelistenergettinginvokedformatchingevent*objectsonly.**@authorRodJohnson*@authorJuergenHoeller*@param