当前位置: 首页 > 后端技术 > Java

基于GuavaAPI的异步通知和事件回调

时间:2023-04-01 22:50:27 Java

本文摘自《设计模式就该这样学》1 基于JavaAPI实现通知机制当朋友在社区提问时,如果有设置指定用户回答,对应的用户会收到邮件通知,这是观察者模式的一个应用场景。有的朋友可能会想到MQ、异步队列等,其实JDK本身就提供了这样的API。我们用代码来还原这样一个应用场景,首先创建GPer类。/***JDK提供的观察者实现,观察者*/publicclassGPerextendsObservable{privateStringname="GPerecosystem";私有静态GPergper=null;privateGPer(){}publicstaticGPergetInstance(){if(null==gper){gper=newGPer();}返回gper;}publicStringgetName(){返回名称;}publicvoidpublishQuestion(Questionquestion){System.out.println(question.getUserName()+"问题提交于"+this.name+"。");设置更改();notifyObservers(问题);}}然后创建问题类。公共类问题{私人字符串用户名;私有字符串内容;publicStringgetUserName(){返回用户名;}publicvoidsetUserName(StringuserName){this.userName=userName;}publicStringgetContent(){返回内容;(字符串内容){this.content=content;}}然后创建教师类。publicclassTeacherimplementsObserver{privateStringname;publicTeacher(Stringname){this.name=name;}publicvoidupdate(Observableo,Objectarg){GPergper=(GPer)o;问题question=(Question)arg;System.out.println("======================");System.out.println(name+"老师,您好!\n"+"您收到了"+gper.getName()+"的问题,希望您能回答。问题内容如下:\n"+question.getContent()+"\n"+"提问者:"+question.getUserName());}}最后,编写客户端测试代码。publicstaticvoidmain(String[]args){GPergper=GPer.getInstance();汤姆老师=newTeacher("汤姆");杰瑞老师=newTeacher("杰瑞");gper.addObserver(汤姆);.addObserver(杰瑞);//用户行为问题question=newQuestion();question.setUserName("张三");question.setContent("观察者模式适用于哪些场景?");gper.publishQuestion(question);}运行结果如下图所示。2 基于GuavaAPI轻松实现观察者模式作者推荐一个非常好用的框架来实现观察者模式。API也非常易于使用。比如先引入Maven依赖包。com.google.guavaguava20.0然后创建监听事件GuavaEvent。/***Tom创建*/publicclassGuavaEvent{@Subscribepublicvoidsubscribe(Stringstr){//业务逻辑System.out.println("执行subscribe方法,传入参数为:"+str);}}最后写客户端测试代码。/***由Tom创建*/publicclassGuavaEventTest{publicstaticvoidmain(String[]args){EventBuseventbus=newEventBus();GuavaEventguavaEvent=newGuavaEvent();eventbus.register(guavaEvent);eventbus.post(“汤姆”);}}3 使用观察者模式设计鼠标事件响应API,然后设计业务场景,帮助小伙伴们更好的理解观察者模式。在JDK源码中,有很多观察者模式的应用。比如java.awt.Event就是一种观察者模式,但是很少用java来写桌面程序。下面我们用代码来实现一下,帮助小伙伴们更深入的了解观察者模式的实现原理。首先,创建EventListener接口。/***观察者抽象*由Tom创建。*/publicinterfaceEventListener{}创建事件类。/***标准事件源格式的定义*由Tom创建。*/publicclassEvent{//事件源,谁发送动作privateObjectsource;//事件触发,通知谁(观察者)privateEventListenertarget;//观察者的回应privateMethodcallback;//事件名称privateStringtrigger;//事件privatelongtime的触发事件;publicEvent(EventListenertarget,Methodcallback){this.target=target;this.callback=回调;}publicObjectgetSource(){返回源;}publicEventsetSource(Objectsource){this.source=source;归还这个;}publicStringgetTrigger(){返回触发器;}publicEventsetTrigger(Stringtrigger){this.trigger=trigger;归还这个;}publiclonggetTime(){返回时间;}publicEventsetTime(longtime){this.time=time;归还这个;}publicMethodgetCallback(){返回回调;}publicEventListenergetTarget(){返回目标;}@OverridepublicStringtoString(){return"Event{"+"source="+source+",target="+target+",callback="+callback+",trigger='"+trigger+'\''+",time="+time+'}';}}创建EventContext类/***被观察者的抽像*由Tom创建。*/publicabstractclassEventContext{protectedMapevents=newHashMap();publicvoidaddListener(StringeventType,EventListenertarget,Methodcallback){events.put(eventType,newEvent(target,callback));}publicvoidaddListener(StringeventType,EventListenertarget){try{this.addListener(eventType,target,target.getClass().getMethod("on"+toUpperFirstCase(eventType),Event.class));}catch(NoSuchMethodExceptione){返回;}}privateStringtoUpperFirstCase(StringeventType){char[]chars=eventType.toCharArray();字符[0]-=32;返回String.valueOf(chars);}privatevoidtrigger(Eventevent){event.setSource(this);event.setTime(System.currentTimeMillis());try{if(event.getCallback()!=null){//用反调用回调函数event.getCallback().invoke(event.getTarget(),事件);}}catch(Exceptione){e.printStackTrace();}}protectedvoidtrigger(Stringtrigger){if(!this.events.containsKey(trigger)){return;}trigger(this.events.get(trigger).setTrigger(trigger));}}然后创建MouseEventType接口/***由Tom创建。*/publicinterfaceMouseEventType{//点击字符串ON_CLICK="click";//双击StringON_DOUBLE_CLICK="doubleClick";//弹起StringON_UP="up";//按下字符串ON_DOWN="down";//移动字符串ON_MOVE="move";//滚动字符串ON_WHEEL="wheel";//悬停字符串ON_OVER="over";//失去焦点StringON_BLUR="blur";//获取焦点StringON_FOCUS="focus";}创建鼠标类。/***特定观察者*由Tom创建。*/publicclassMouseextendsEventContext{publicvoidclick(){System.out.println("调用点击方法");this.trigger(MouseEventType.ON_CLICK);}publicvoiddoubleClick(){System.out.println("调用双击方法");this.trigger(MouseEventType.ON_DOUBLE_CLICK);}publicvoidup(){System.out.println("调用弹出方法");this.trigger(MouseEventType.ON_UP);}publicvoiddown(){System.out.println("调用press方法");this.trigger(MouseEventType.ON_DOWN);}publicvoidmove(){System.out.println("调用移动方法");this.trigger(MouseEventType.ON_MOVE);}publicvoidwheel(){System.out.println("调用了Roll方法");this.trigger(MouseEventType.ON_WHEEL);}publicvoidover(){System.out.println("调用悬停方法");this.trigger(MouseEventType.ON_OVER);}publicvoidblur(){System.out.println("调用焦点方法");这个.trigger(MouseEventType.ON_模糊);}publicvoidfocus(){System.out.println("调用失去焦点方法");this.trigger(MouseEventType.ON_FOCUS);}}创建回调方法MouseEventLisenter类/***Observer*由Tom创建。*/publicclassMouseEventListenerimplementsEventListener{publicvoidonClick(Evente){System.out.println("===========触发鼠标点击事件=========="+"\n"+e);}publicvoidonDoubleClick(Evente){System.out.println("===========触发鼠标双击事件=========="+"\n"+e);}publicvoidonUp(Evente){System.out.println("===========触发鼠标Popup事件==========="+"\n"+e);}publicvoidonDown(Evente){System.out.println("===========触发鼠标按下事件=========="+"\n"+e);}publicvoidonMove(Evente){System.out.println("===========触发鼠标移动事件=========="+"\n"+e);}publicvoidonWheel(Evente){System.out.println("===========触发鼠标滚动事件=========="+"\n"+e);}publicvoidonOver(Evente){System.out.println("===========触发鼠标悬停事件=========="+"\n"+e);}publicvoidonBlur(Evente){System.out.println("===========触发鼠标失去焦点事件=========="+"\n"+e);}publicvoidonFocus(Evente){System.out.println("===========触发鼠标焦点事件=========="+"\n"+e);}}最后编写客户端测试代码publicstaticvoidmain(String[]args){EventListenerlistener=newMouseEventListener();鼠标mouse=newMouse();mouse.addListener(MouseEventType.ON_CLICK,listener);老鼠。添加监听器(MouseEventType.ON_MOVE,监听器);鼠标点击();鼠标移动();}关注微信公众号『汤姆炸弹架构』回复“设计模式”获取完整源码。【推荐】汤姆炸弹架构:30个设计模式实战案例(附源码),挑战60W年薪不是梦技术在于分享,我分享我的快乐!如果本文对您有帮助,请关注并点赞;有什么建议也可以留言或私信。您的支持是我坚持创作的动力。关注微信公众号“汤姆炸弹架构”,获取更多技术干货!