java实现多路分发
http://blog.csdn.net/godwanglong/article/details/7937668
多路分发就是指在调用a.plus(b),a和b都不知道确切类型,也能让他们正常交互。
如果想使用两路分发,那么必须有两个方法调用,第一个方法调用决定第一个未知类型,第二个方法调用决定第二个未知类型。要利用多路分发,程序员必须为每一个类型提供给一个实际的方法调用。一般而言,程序员需要设定好某种配置,以便一个方法调用能够引出更多的方法调用,从而能在这个过程中处理多个类型。
下面是个“石头 剪刀 布”(RoShamBo)游戏的例子 (from: thinking in java):
- public enum Outcome { WIN, LOSE, DRAW } ///:~
- interface Item {
- Outcome compete(Item it);
- Outcome eval(Paper p);
- Outcome eval(Scissors s);
- Outcome eval(Rock r);
- }
- class Paper implements Item {
- public Outcome compete(Item it) {
- return it.eval(this);
- }
- public Outcome eval(Paper p) {
- return DRAW;
- }
- public Outcome eval(Scissors s) {
- return WIN;
- }
- public Outcome eval(Rock r) {
- return LOSE;
- }
- public String toString() {
- return "Paper";
- }
- }
- class Scissors implements Item {
- public Outcome compete(Item it) {
- return it.eval(this);
- }
- public Outcome eval(Paper p) {
- return LOSE;
- }
- public Outcome eval(Scissors s) {
- return DRAW;
- }
- public Outcome eval(Rock r) {
- return WIN;
- }
- public String toString() {
- return "Scissors";
- }
- }
- class Rock implements Item {
- public Outcome compete(Item it) {
- return it.eval(this);
- }
- public Outcome eval(Paper p) {
- return WIN;
- }
- public Outcome eval(Scissors s) {
- return LOSE;
- }
- public Outcome eval(Rock r) {
- return DRAW;
- }
- public String toString() {
- return "Rock";
- }
- }
- public class RoShamBo1 {
- static final int SIZE = 20;
- private static Random rand = new Random(47);
- public static Item newItem() {
- switch (rand.nextInt(3)) {
- default:
- case 0:
- return new Scissors();
- case 1:
- return new Paper();
- case 2:
- return new Rock();
- }
- }
- public static void match(Item a, Item b) {
- System.out.println(a + " vs. " + b + ": " + a.compete(b));
- }
- public static void main(String[] args) {
- for (int i = 0; i < SIZE; i++)
- match(newItem(), newItem());
- }
- }
RoshamBol.match()有2个item参数,通关过Item.compete()方法开始2路分发,要判定a的类型,分发机制会在a的实际类型的compete()内部起到分发作用。compete()方法通关过eval()来为另一个类型实现第二次分发, 将自身(this)作为参数调用eval(),能够调用重载过的eval()方法,这能够保留第一次分发的类型信息,第二次分发完成时,就能知道两个Item对象的具体类型了。
用上述方法,就能避免 if else的书写和获取对象具体类型的方法
这种方法的精妙之处在于,通过调用 item1的compete方法,实现对item1的类型的分发,而在item1的compete方法中,用通过调用item2的eval方法,将自身this昨晚参数,实现了Item2中eval方法的分发
使用EnumMap分发:
- enum RoShamBo5 implements Competitor<RoShamBo5> {
- PAPER, SCISSORS, ROCK;
- static EnumMap<RoShamBo5, EnumMap<RoShamBo5, Outcome>> table = new EnumMap<RoShamBo5, EnumMap<RoShamBo5, Outcome>>(
- RoShamBo5.class);
- static {
- for (RoShamBo5 it : RoShamBo5.values())
- table.put(it, new EnumMap<RoShamBo5, Outcome>(RoShamBo5.class));
- initRow(PAPER, DRAW, LOSE, WIN);
- initRow(SCISSORS, WIN, DRAW, LOSE);
- initRow(ROCK, LOSE, WIN, DRAW);
- }
- static void initRow(RoShamBo5 it, Outcome vPAPER, Outcome vSCISSORS,
- Outcome vROCK) {
- EnumMap<RoShamBo5, Outcome> row = RoShamBo5.table.get(it);
- row.put(RoShamBo5.PAPER, vPAPER);
- row.put(RoShamBo5.SCISSORS, vSCISSORS);
- row.put(RoShamBo5.ROCK, vROCK);
- }
- public Outcome compete(RoShamBo5 it) {
- return table.get(this).get(it);
- }
- public static void main(String[] args) {
- RoShamBo.play(RoShamBo5.class, 20);
- }
- }
- public class RoShamBo {
- public static <T extends Competitor<T>> void match(T a, T b) {
- System.out.println(a + " vs. " + b + ": " + a.compete(b));
- }
- public static <T extends Enum<T> & Competitor<T>> void play(
- Class<T> rsbClass, int size) {
- for (int i = 0; i < size; i++)
- match(Enums.random(rsbClass), Enums.random(rsbClass));
- }
- }
java实现多路分发相关推荐
- java 多路分发_java实现多路分发
多路分发就是指在调用a.plus(b),a和b都不知道确切类型,也能让他们正常交互. 如果想使用两路分发,那么必须有两个方法调用,第一个方法调用决定第一个未知类型,第二个方法调用决定第二个未知类型.要 ...
- java实现分发_关于JAVA中事件分发和监听机制实现的代码实例
[实例简介] 关于JAVA中事件分发和监听机制实现的代码实例,绝对实用代码,有说明. [实例截图] [核心代码] JavaEventDispatch ├── bin │ └── com │ └ ...
- 关于JAVA中事件分发和监听机制实现的代码实例-绝对原创实用
转载:http://blog.csdn.net/5iasp/article/details/37054171 谢谢博主 ======================================== ...
- java 多线程数据分发_使用Java多线程实现任务分发
多线程下载由来已久,如 FlashGet.NetAnts 等工具,它们都是依懒于 HTTP 协议的支持(Range 字段指定请求内容范围),首先能读取出请求内容 (即欲下载的文件) 的大小,划分出若干 ...
- 苹果ios超级签名源码包java版带分发页面支持安卓合并部署教程
果超级签名是什么我就不在赘述了,项目由java+vue开发 功能: 1.支持登录注册,拥有共有池,可上传证书等基本操作,支持用户自行上传证书 2.支持修改分发页面轮播图,简介,安卓合并 3.ipa签名 ...
- 苹果ios超级签名源码包java版带分发页面支持安卓合并
苹果超级签名是什么我就不在赘述了,项目由java+vue开发 功能: 1.支持登录注册,拥有共有池,可上传证书等基本操作,支持用户自行上传证书 2.支持修改分发页面轮播图,简介,安卓合并 3.ipa签 ...
- java 多线程数据分发_多线程分发处理List集合数据
//List集合 final List plyVO = plyDayListDao.selectPlyDayListKey(dataSumNo,sd,tstate); if(plyVO != null ...
- java visitor_Java 的双重分发与 Visitor 模式
双重分发(Double Dispatch) 什么是双重分发? 谈起面向对象的程序设计时,常说起的面向对象的「多态」,其中关于多态,经常有一个说法是「父类引用指向子类对象」. 这种父类的引用指向子类对象 ...
- Java enum的用法详解
在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. public e ...
最新文章
- Nature-2018-抗菌药物组合有望特异性治疗耐多药性的细菌感染
- python实现登录网站下载文件-Python爬虫 登录网页后下载图片,怎么保持登录状态?...
- 一些经常会用到的vbscript检测函数
- 节流函数(throttle)的原理
- 联想电脑怎么进入Android,联想电脑怎么连接手机
- C++实现顺序栈的基本功能
- 在php中怎么引用已经定义过的变量,变量已经在方法中定义但执行的时候还报错?...
- 怎么设置数据库服务器的最佳性能,调整Windows参数提高数据库服务器性能
- 这两款无“节操”的浏览器,在315被曝光后,终于被下架了
- Object_id用法
- TIOBE 10月编程语言排行榜 : GO 问鼎本年度语言 ?
- unsupported major.monor version 51.0 (unable to load *.servlet)………………
- 百度网盘怎么登录百度账号?
- cmd命令快速切换电源模式-平衡模式和卓越模式
- LabVIEW编程LabVIEW开发 施耐德
- 【面试概率】52张扑克牌,红桃A和黑桃A同时被一个人拿到的概率
- java:利用数组实现将古诗词纵向输出
- “新产业50人论坛”之清华龙桂鲁教授:量子信息与创新发展
- i7 10700k和i9 9900k对比哪个好
- Jenkins凭据导出
热门文章
- php查询一对多,PHP并输出一对多结果
- 【小白学习PyTorch教程】十七、 PyTorch 中 数据集torchvision和torchtext
- 十一、深入JavaScript的定时器(七)
- CoSENT:比Sentence-BERT更有效的句向量方案
- 深度强化学习探索算法最新综述,近200篇文献揭示挑战和未来方向
- NeurIPS 2020 | 自步对比学习:充分挖掘无监督学习样本
- 这场论文复现的华山论剑,谁能拔得头筹
- Java 实现 Trie (前缀树)
- android d-bus,android EventBus的使用
- linux算术表达式求值数据结构,数据结构:算数表达式求值演示