http://blog.csdn.net/godwanglong/article/details/7937668

多路分发就是指在调用a.plus(b),a和b都不知道确切类型,也能让他们正常交互。

如果想使用两路分发,那么必须有两个方法调用,第一个方法调用决定第一个未知类型,第二个方法调用决定第二个未知类型。要利用多路分发,程序员必须为每一个类型提供给一个实际的方法调用。一般而言,程序员需要设定好某种配置,以便一个方法调用能够引出更多的方法调用,从而能在这个过程中处理多个类型。

下面是个“石头 剪刀 布”(RoShamBo)游戏的例子 (from: thinking in java):

[java] view plaincopy
  1. public enum Outcome { WIN, LOSE, DRAW } ///:~
  2. interface Item {
  3. Outcome compete(Item it);
  4. Outcome eval(Paper p);
  5. Outcome eval(Scissors s);
  6. Outcome eval(Rock r);
  7. }
  8. class Paper implements Item {
  9. public Outcome compete(Item it) {
  10. return it.eval(this);
  11. }
  12. public Outcome eval(Paper p) {
  13. return DRAW;
  14. }
  15. public Outcome eval(Scissors s) {
  16. return WIN;
  17. }
  18. public Outcome eval(Rock r) {
  19. return LOSE;
  20. }
  21. public String toString() {
  22. return "Paper";
  23. }
  24. }
  25. class Scissors implements Item {
  26. public Outcome compete(Item it) {
  27. return it.eval(this);
  28. }
  29. public Outcome eval(Paper p) {
  30. return LOSE;
  31. }
  32. public Outcome eval(Scissors s) {
  33. return DRAW;
  34. }
  35. public Outcome eval(Rock r) {
  36. return WIN;
  37. }
  38. public String toString() {
  39. return "Scissors";
  40. }
  41. }
  42. class Rock implements Item {
  43. public Outcome compete(Item it) {
  44. return it.eval(this);
  45. }
  46. public Outcome eval(Paper p) {
  47. return WIN;
  48. }
  49. public Outcome eval(Scissors s) {
  50. return LOSE;
  51. }
  52. public Outcome eval(Rock r) {
  53. return DRAW;
  54. }
  55. public String toString() {
  56. return "Rock";
  57. }
  58. }
  59. public class RoShamBo1 {
  60. static final int SIZE = 20;
  61. private static Random rand = new Random(47);
  62. public static Item newItem() {
  63. switch (rand.nextInt(3)) {
  64. default:
  65. case 0:
  66. return new Scissors();
  67. case 1:
  68. return new Paper();
  69. case 2:
  70. return new Rock();
  71. }
  72. }
  73. public static void match(Item a, Item b) {
  74. System.out.println(a + " vs. " + b + ": " + a.compete(b));
  75. }
  76. public static void main(String[] args) {
  77. for (int i = 0; i < SIZE; i++)
  78. match(newItem(), newItem());
  79. }
  80. }

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分发:

[java] view plaincopy
  1. enum RoShamBo5 implements Competitor<RoShamBo5> {
  2. PAPER, SCISSORS, ROCK;
  3. static EnumMap<RoShamBo5, EnumMap<RoShamBo5, Outcome>> table = new EnumMap<RoShamBo5, EnumMap<RoShamBo5, Outcome>>(
  4. RoShamBo5.class);
  5. static {
  6. for (RoShamBo5 it : RoShamBo5.values())
  7. table.put(it, new EnumMap<RoShamBo5, Outcome>(RoShamBo5.class));
  8. initRow(PAPER, DRAW, LOSE, WIN);
  9. initRow(SCISSORS, WIN, DRAW, LOSE);
  10. initRow(ROCK, LOSE, WIN, DRAW);
  11. }
  12. static void initRow(RoShamBo5 it, Outcome vPAPER, Outcome vSCISSORS,
  13. Outcome vROCK) {
  14. EnumMap<RoShamBo5, Outcome> row = RoShamBo5.table.get(it);
  15. row.put(RoShamBo5.PAPER, vPAPER);
  16. row.put(RoShamBo5.SCISSORS, vSCISSORS);
  17. row.put(RoShamBo5.ROCK, vROCK);
  18. }
  19. public Outcome compete(RoShamBo5 it) {
  20. return table.get(this).get(it);
  21. }
  22. public static void main(String[] args) {
  23. RoShamBo.play(RoShamBo5.class, 20);
  24. }
  25. }
  26. public class RoShamBo {
  27. public static <T extends Competitor<T>> void match(T a, T b) {
  28. System.out.println(a + " vs. " + b + ": " + a.compete(b));
  29. }
  30. public static <T extends Enum<T> & Competitor<T>> void play(
  31. Class<T> rsbClass, int size) {
  32. for (int i = 0; i < size; i++)
  33. match(Enums.random(rsbClass), Enums.random(rsbClass));
  34. }
  35. }

java实现多路分发相关推荐

  1. java 多路分发_java实现多路分发

    多路分发就是指在调用a.plus(b),a和b都不知道确切类型,也能让他们正常交互. 如果想使用两路分发,那么必须有两个方法调用,第一个方法调用决定第一个未知类型,第二个方法调用决定第二个未知类型.要 ...

  2. java实现分发_关于JAVA中事件分发和监听机制实现的代码实例

    [实例简介] 关于JAVA中事件分发和监听机制实现的代码实例,绝对实用代码,有说明. [实例截图] [核心代码] JavaEventDispatch ├── bin │   └── com │   └ ...

  3. 关于JAVA中事件分发和监听机制实现的代码实例-绝对原创实用

    转载:http://blog.csdn.net/5iasp/article/details/37054171 谢谢博主 ======================================== ...

  4. java 多线程数据分发_使用Java多线程实现任务分发

    多线程下载由来已久,如 FlashGet.NetAnts 等工具,它们都是依懒于 HTTP 协议的支持(Range 字段指定请求内容范围),首先能读取出请求内容 (即欲下载的文件) 的大小,划分出若干 ...

  5. 苹果ios超级签名源码包java版带分发页面支持安卓合并部署教程

    果超级签名是什么我就不在赘述了,项目由java+vue开发 功能: 1.支持登录注册,拥有共有池,可上传证书等基本操作,支持用户自行上传证书 2.支持修改分发页面轮播图,简介,安卓合并 3.ipa签名 ...

  6. 苹果ios超级签名源码包java版带分发页面支持安卓合并

    苹果超级签名是什么我就不在赘述了,项目由java+vue开发 功能: 1.支持登录注册,拥有共有池,可上传证书等基本操作,支持用户自行上传证书 2.支持修改分发页面轮播图,简介,安卓合并 3.ipa签 ...

  7. java 多线程数据分发_多线程分发处理List集合数据

    //List集合 final List plyVO = plyDayListDao.selectPlyDayListKey(dataSumNo,sd,tstate); if(plyVO != null ...

  8. java visitor_Java 的双重分发与 Visitor 模式

    双重分发(Double Dispatch) 什么是双重分发? 谈起面向对象的程序设计时,常说起的面向对象的「多态」,其中关于多态,经常有一个说法是「父类引用指向子类对象」. 这种父类的引用指向子类对象 ...

  9. Java enum的用法详解

    在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. public e ...

最新文章

  1. Nature-2018-抗菌药物组合有望特异性治疗耐多药性的细菌感染
  2. python实现登录网站下载文件-Python爬虫 登录网页后下载图片,怎么保持登录状态?...
  3. 一些经常会用到的vbscript检测函数
  4. 节流函数(throttle)的原理
  5. 联想电脑怎么进入Android,联想电脑怎么连接手机
  6. C++实现顺序栈的基本功能
  7. 在php中怎么引用已经定义过的变量,变量已经在方法中定义但执行的时候还报错?...
  8. 怎么设置数据库服务器的最佳性能,调整Windows参数提高数据库服务器性能
  9. 这两款无“节操”的浏览器,在315被曝光后,终于被下架了
  10. Object_id用法
  11. TIOBE 10月编程语言排行榜 : GO 问鼎本年度语言 ?
  12. unsupported major.monor version 51.0 (unable to load *.servlet)………………
  13. 百度网盘怎么登录百度账号?
  14. cmd命令快速切换电源模式-平衡模式和卓越模式
  15. LabVIEW编程LabVIEW开发 施耐德
  16. 【面试概率】52张扑克牌,红桃A和黑桃A同时被一个人拿到的概率
  17. java:利用数组实现将古诗词纵向输出
  18. “新产业50人论坛”之清华龙桂鲁教授:量子信息与创新发展
  19. i7 10700k和i9 9900k对比哪个好
  20. Jenkins凭据导出

热门文章

  1. php查询一对多,PHP并输出一对多结果
  2. 【小白学习PyTorch教程】十七、 PyTorch 中 数据集torchvision和torchtext
  3. 十一、深入JavaScript的定时器(七)
  4. CoSENT:比Sentence-BERT更有效的句向量方案
  5. 深度强化学习探索算法最新综述,近200篇文献揭示挑战和未来方向
  6. NeurIPS 2020 | 自步对比学习:充分挖掘无监督学习样本
  7. 这场论文复现的华山论剑,谁能拔得头筹
  8. Java 实现 Trie (前缀树)
  9. android d-bus,android EventBus的使用
  10. linux算术表达式求值数据结构,数据结构:算数表达式求值演示