生活随笔
收集整理的這篇文章主要介紹了
java实现多路分发
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://blog.csdn.net/godwanglong/article/details/7937668
多路分發就是指在調用a.plus(b),a和b都不知道確切類型,也能讓他們正常交互。
? ? 如果想使用兩路分發,那么必須有兩個方法調用,第一個方法調用決定第一個未知類型,第二個方法調用決定第二個未知類型。要利用多路分發,程序員必須為每一個類型提供給一個實際的方法調用。一般而言,程序員需要設定好某種配置,以便一個方法調用能夠引出更多的方法調用,從而能在這個過程中處理多個類型。
? ?下面是個“石頭 剪刀 布”(RoShamBo)游戲的例子 (from: thinking in java):
[java]?view plaincopy
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分發:
[java]?view plaincopy
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实现多路分发的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。