Java观察者模式事件委托(通过dota和王者荣耀故事讲解)
故事情景
首先介绍下故事的三位同学,阿顾、蛋蛋和洋洋,蛋蛋,洋洋喜欢玩游戏,但是又生怕班主任回来了被抓到,所以他们就找到了阿顾同学帮他们把风,但是阿顾同学不是谁都通知的,只有到阿顾那里登记的,阿顾同学才会通知这些登记的人,下面我们来模拟下整个流程:
蛋蛋说:“阿顾,我在玩dota,班主任回来了,通知一声”
阿顾说:“好的,我记录一下”
洋洋说:“阿顾,我在玩王者荣耀,班主任回来了,通知一声”
阿顾说:“好的,我记录一下”
阿顾此时正在把风,过了一会,发现班主任回来了,立马通知刚刚在这里登记的蛋蛋和洋洋同学
蛋蛋立即关闭dota,继续学习;洋洋立即关闭王者荣耀,继续学习(流程结束)
到这里,我们看一下代码
目录
故事情景
一 观察者模式
1.1 代码结构
1.2 主题
1.3 观察者(抽象类)
1.4 阿顾同学
1.5 蛋蛋同学
1.6 洋洋同学
1.7 测试
1.8 运行结果
1.9 观察者模式的优缺点
1.9.1 优点
1.9.2 缺点
1.9.3 解决缺点
二 事件委托
2.1 代码结构
2.2 事件类
2.3 事件处理类
2.4 通知者(抽象类)
2.5 阿顾同学
2.6 蛋蛋同学
2.7 洋洋同学
2.8 测试
2.9 运行结果
三 参考文献
四 源码地址
一 观察者模式
1.1 代码结构
1.2 主题
主题是一个接口,提供了观察者抽象类添加方法,移除方法,以及通知功能
public interface Subject {//增加观察者public void add(Observer observer);//移除观察者public void remove(Observer observer);//通知观察者public void notifyObserver();}
1.3 观察者(抽象类)
/*** 观察者(抽象类)*/
public abstract class Observer {//抽象方法(停止做某事)public abstract void stopDoingSomeThing();
}
1.4 阿顾同学
这里实现了主题,并且添加了一个观察者抽象类的集合,所以登记的同学都放到这个集合里,如果发现班主任回来了,直接直接执行通知方法(遍历集合里的同学)
public class AguSubject implements Subject {//主题状态private String subjectState;public String getSubjectState() {return subjectState;}public void setSubjectState(String subjectState) {this.subjectState = subjectState;}//观察者列表(所有需要通知的对象都会放到这个集合里)private List<Observer> observerList =new ArrayList<Observer>();//添加观察者public void add(Observer observer) {observerList.add(observer);}//移除观察者public void remove(Observer observer) {observerList.remove(observer);}//通知观察者public void notifyObserver() {for (Observer observer : observerList) {//父类执行这个方法,执行的是子类重写的方法observer.stopDoingSomeThing();}}
}
1.5 蛋蛋同学
public class DanDanObserver extends Observer {//姓名private String name;//阿顾同学private AguSubject subject;//有参构造函数public DanDanObserver(String name, AguSubject subject) {this.name = name;this.subject = subject;}//重写父类方法public void stopDoingSomeThing() {System.out.println(subject.getSubjectState() + this.name + "关闭了<dota2>,继续学习");}
}
1.6 洋洋同学
public class YangYangObserver extends Observer {//姓名private String name;//阿顾同学private AguSubject subject;//有参构造函数public YangYangObserver(String name,AguSubject subject){this.name=name;this.subject=subject;}//重写父类方法public void stopDoingSomeThing() {System.out.println(subject.getSubjectState()+this.name+"关闭了<王者荣耀>,继续学习");}
}
1.7 测试
public class AppStart {public static void main(String[] args) {//创建阿顾同学(负责把风)AguSubject aguSubject = new AguSubject();//创建蛋蛋DanDanObserver danObserver = new DanDanObserver("蛋蛋", aguSubject);//创建洋洋YangYangObserver yangObserver = new YangYangObserver("洋洋", aguSubject);//蛋蛋在阿顾同学那登记,如果老师来了通知下aguSubject.add(danObserver);//洋洋在阿顾同学那登记,如果老师来了通知下aguSubject.add(yangObserver);//阿顾发现老师回来了aguSubject.setSubjectState("老师回来了----");//通知所有登记过的同学aguSubject.notifyObserver();}
}
1.8 运行结果
1.9 观察者模式的优缺点
1.9.1 优点
1. 观察者和主题进行了不错的解耦
1.9.2 缺点
1.主题还是要依赖抽象观察者(Subject里的方法要传入Observer),如果没有抽象观察者呢
2.每个具体的观察者方法都一样(蛋蛋和洋洋里都要重写stopDoingSomething()方法,并且他们的方法名和参数是一样的)
1.9.3 解决缺点
通过事件委托可以解决
二 事件委托
2.1 代码结构
2.2 事件类
这里是把一个对象,对象的方法,方法的参数 封装到事件类中,这样拿到事件,就拿到了对象的方法,就可以直接执行对应的方法了
/*** 事件类,就是将一个对象,对象的方法,方法中的参数 作为事件类的属性*/
public class Event {//要执行方法的对象private Object object;//要执行方法的方法名private String methodName;//要执行方法的参数private Object[] params;//要执行方法的参数的类型private Class[] paramTypes;//无惨构造函数public Event() {}public Event(Object object, String methodName, Object... args) {this.object = object;this.methodName = methodName;this.params = args;generateParamTypes(args);}//获取执行方法的参数的类型public void generateParamTypes(Object[] args) {this.paramTypes = new Class[args.length];for (int i = 0; i < args.length; i++) {paramTypes[i] = args[i].getClass();}}//方法的执行public void invoke() throws Exception {//通过反射以及方法名和参数类型获取到对应的方法Method method = object.getClass().getMethod(this.getMethodName(), this.getParamTypes());if(null==method){return;}//方法执行method.invoke(this.getObject(),this.getParams());}//get和set方法省略...
}
2.3 事件处理类
这里又将Event的集合封装到EventHandler中
public class EventHandler {//事件列表(就是传进来某个对象的方法的一个集合)private List<Event> eventList;public EventHandler() {eventList = new ArrayList<Event>();}//添加某个对象要执行的方法,及参数public void addEvent(Object object, String methodName, Object... args) {Event event = new Event(object, methodName, args);eventList.add(event);}//通知所有观察者public void notifyObserver() throws Exception {for (Event e : eventList) {e.invoke();}}
}
2.4 通知者(抽象类)
这里又将EventHandler封装到Notifier中
public abstract class Notifier {private EventHandler eventHandler = new EventHandler();public EventHandler getEventHandler() {return eventHandler;}public void setEventHandler(EventHandler eventHandler) {this.eventHandler = eventHandler;}/*** 增加需要被通知的对象* @param object 要执行方法的对象* @param methodName 执行方法的方法名* @param args 执行方法的参数*/public abstract void addListener(Object object, String methodName, Object... args);//通知public abstract void notifyObserver() throws Exception;}
2.5 阿顾同学
public class AguNotifier extends Notifier {//添加public void addListener(Object object, String methodName, Object... args) {System.out.println("有新的同学委托阿顾");this.getEventHandler().addEvent(object, methodName, args);}//通知public void notifyObserver() throws Exception {System.out.println("======阿顾同学正在观察...班主任来了没======");Thread.sleep(2000);System.out.println("过了2秒后,阿顾通知:班主任人来了");this.getEventHandler().notifyObserver();}
}
2.6 蛋蛋同学
public class DanDanObserver {public DanDanObserver(){System.out.println("蛋蛋 正在打dota2,时间:"+new Date());}public void stopPlayDota2(String book){System.out.println("蛋蛋 关闭了dota2,继续学习"+book+",时间:"+new Date());}
}
2.7 洋洋同学
public class YangYangObserver {public YangYangObserver() {System.out.println("洋洋 正在打王者荣耀,时间:"+new Date());}public void stopKingGlory(Double javaVersion) {System.out.println("洋洋 关闭了王者荣耀,继续研究java"+javaVersion+"新特性,时间:" + new Date());}
}
2.8 测试
public class AppStart {public static void main(String[] args) {//专门把风的阿顾同学AguNotifier aguNotifier = new AguNotifier();//玩dota2的蛋蛋同学DanDanObserver danDanObserver = new DanDanObserver();//玩王者的洋洋同学YangYangObserver yangYangObserver = new YangYangObserver();//玩dota2的蛋蛋让阿顾帮忙看一下,如果班主任来了通知下aguNotifier.addListener(danDanObserver,"stopPlayDota2","<java编程思想>");//玩王者的洋洋让阿顾帮忙看一下,如果班主任来了通知下aguNotifier.addListener(yangYangObserver,"stopKingGlory",1.8);try {//阿顾开始通知aguNotifier.notifyObserver();} catch (Exception e) {e.printStackTrace();}}
}
2.9 运行结果
三 参考文献
1.大话设计模式
2.https://blog.csdn.net/gdutxiaoxu/article/details/51824769
四 源码地址
https://github.com/guguoyu/event-handler
Java观察者模式事件委托(通过dota和王者荣耀故事讲解)相关推荐
- 王者荣耀故事站小程序(nuxt + 小程序)
前言 一直想学习开发一款小程序,无奈拖延至今,恰逢王者荣耀周年庆,然后本人对王者英雄的人物.配音比较感兴趣,就有开发一款王者荣耀故事站的小程序的念头.想要了解故事背景就直接打开小程序就好了. ps: ...
- 王者荣耀故事站小程序(nuxt + 小程序) 1
前言 一直想学习开发一款小程序,无奈拖延至今,恰逢王者荣耀周年庆,然后本人对王者英雄的人物.配音比较感兴趣,就有开发一款王者荣耀故事站的小程序的念头.想要了解故事背景就直接打开小程序就好了. ps: ...
- Java项目你们期待的热门游戏-王者荣耀
相信很多小伙伴都玩游戏,而对于王者荣耀大家更是不陌生了.虽然王者荣耀在网上的不评论很不好,但是大多数还是逃不过真香定律,边吐槽边玩. 人类已经很难阻止<王者荣耀>前进的步伐了,进入2017 ...
- 实训代码java毕业设计_基于SSM框架的王者荣耀游戏攻略系统
基于SSM框架的王者荣耀游戏攻略系统mysql数据库创建语句 基于SSM框架的王者荣耀游戏攻略系统oracle数据库创建语句 基于SSM框架的王者荣耀游戏攻略系统sqlserver数据库创建语句 基于 ...
- LoL、DOTA、王者荣耀类游戏小地图注册及相机的跟随
有几天没有更新博客了,在做一个塔防的小游戏,然而想着想着功能就多了,感觉可以做成一个小型的单机游戏了,我会在接下来的几篇博客把这个项目的一些功能及获得的感悟呈现给大家,今天继续上次的视角变动,在鼠标指 ...
- 王者荣耀故事站小程序源码/含vue后台
介绍: 淘宝买的,直接分享给大家了,没有测试环境,也没有办法去测.但我想,他应该是可以用的.东西如下图,喜欢的自己拿去吧. 网盘下载地址: http://nb8.net/zEbYH9i9a7g0 图片 ...
- (Java)2021年最新-王者荣耀游戏开发
<王者荣耀>是由腾讯游戏天美工作室群开发并运行的一款运营在Android.IOS.NS平台上的MOBA类国产手游,于2015年11月26日在Android.iOS平台上正式公测. 王者荣耀 ...
- Java游戏项目之王者荣耀
说起腾讯游戏,想必不少人最先想到的是<王者荣耀>这款当下热门手游. 王者荣耀中的玩法以竞技对战为主,玩家之间进行多种方式的PVP对战,还可以参加游戏的冒险模式,进行PVE的闯关模式,在满足 ...
- Java游戏项目:王者荣耀项目源码分享
说起腾讯游戏,想必不少人最先想到的是<王者荣耀>这款当下热门手游. 王者荣耀中的玩法以竞技对战为主,玩家之间进行多种方式的PVP对战,还可以参加游戏的冒险模式,进行PVE的闯关模式,在满足 ...
最新文章
- Fedora配置网络DHCP
- spring tx:advice 和 aop:config 配置事务
- java模拟浏览器不关闭会话_JSP实现浏览器关闭cookies情况下的会话管理
- java 打印心形图案_简单漂亮的心形礼品盒折纸手工教程
- C#LeetCode刷题之#840-矩阵中的幻方(Magic Squares In Grid)
- Luogu 3625 [APIO2009]采油区域
- POJ - 2069 Super Star HDU - 3007 Buried memory
- Ajax:异步JavaScript和XML的笔记略解,不作为知识参考
- AltiumDesigner(三):PCB导出Gerber文件及各个Gerber文件说明
- bmp怎样转成jpg,bmp格式换jpg
- 本周(12.23-12.29)半价电子书
- IT4IT 标准助力 IT 经理控制乱局
- cura切片操作学习
- 亚马逊测评到底是一个什么样的项目流程?测评新风口,深度解析
- 大学计算机基础教学目标,大学计算机基础教学大纲2015.doc
- mysql 多个主码_数据库中几个基本概念 主码 外码
- 史上接近最完整的选择屏幕开发知识(针对初学者)(还有下拉菜单的实现)
- c语言-基础知识点复习
- ✨英语学习|如何高效做英语阅读笔记
- 【从0到1搭建LoRa物联网】4、国产LoRa终端ASR6505普通GPIO
热门文章
- 主平台对接多个系统,系统表的性能和对接方案
- c++语言字母转换,c++大小写字母转换的思路有几种?
- 远程控制网吧服务器,方便维修,电脑坏了不用愁,向日葵电脑远程维修省时又省力...
- 【梅哥的Ring0湿润插入教程】第一课Windows内核/驱动编程概述及应用、商业驱动保护软件原理分析...
- js实现1-100以内的质数
- 搜索:多模态搜索算法实践【工业界:将其他模态(视频、音频)的信息降维到文本模态】【学术界:将所有模型信息映射到公共向量空间】
- [H5]HTML5样式、链接和表格
- python预测未来数据步骤_大神教你用Python预测未来:一文看懂时间序列(值得收藏)...
- Git - Smart Checkout、Force Checkout 区别
- C++——模板与STL标准模板库