图解设计模式-Strategy模式
Strategy(算法)模式可以整体的替换算法的实现部分。
重点说明:
使用委托这种弱关联关系可以很方便的整体替换算法。
角色:
Strategy策略:该角色负责决定实现策略所需要的接口api。
ConcreteStrategy具体策略:该角色负责实现Strategy角色接口api。即负责实现具体的策略。
Context上下文:负责使用Strategy角色,Context角色保存了ConcreteStrategy角色的实例,并使用ConcreteStrategy角色去实现需求。
代码:
public class Hand { public static final int GUU = 0; public static final int CHO = 1; public static final int PAA = 2; public static final Hand[] hand = { new Hand(GUU), new Hand(CHO), new Hand(PAA), }; private int handValue; private Hand(int handValue) { this.handValue = handValue; } private static final String[] name = { "石头","剪刀","布" }; public static Hand getHand(int handValue) { return hand[handValue]; } public boolean isStrongerThan(Hand h){ return fight(h)== 1; } public boolean isWeakerThan(Hand h) { return fight(h)== -1; } private int fight(Hand h) { if(this==h){ return 0; }else if((this.handValue+1)%3==h.handValue) { return 1; }else{ return -1; } } }
public interface Strategy { public abstract Hand nextHand(); public abstract void study(boolean win); }
public class ProbStrategy implements Strategy { private Random random; private int preHandValue = 0; private int currentHandValue =0; private int[][] histroy = { {1,1,1}, {1,1,1}, {1,1,1} }; public ProbStrategy(int seed) { this.random = new Random(seed); } private int getSum(int hv) { int sum = 0; for(int i=0;i<3;i++) { sum +=histroy[hv][i]; } return sum; } @Override public Hand nextHand() { int bet = random.nextInt(getSum(currentHandValue)); int handvalue = 0; if(bet<histroy[currentHandValue][0]) { handvalue=0; }else if(bet<histroy[currentHandValue][0] + histroy[currentHandValue][1]) { handvalue =1; }else { handvalue = 2; } preHandValue=currentHandValue; currentHandValue = handvalue; return Hand.getHand(handvalue); } @Override public void study(boolean win) { if(win){ histroy[preHandValue][currentHandValue]++; }else { histroy[preHandValue][(currentHandValue+1)%3]++; histroy[preHandValue][(currentHandValue+2)%3]++; } } }
public class WinningStrategy implements Strategy { private Random random; private boolean won =false; private Hand preHand; public WinningStrategy(int seed) { this.random = new Random(seed); } @Override public Hand nextHand() { if(!won) { preHand = Hand.getHand(random.nextInt(3)); } return preHand; } @Override public void study(boolean win) { won = win; } }
public class Main { public static void main(String[] args){ int seed0=1; int seed1=2; Play play1 = new Play("王五",new WinningStrategy(seed0)); Play play2 = new Play("王五",new ProbStrategy(seed1)); for(int i=0;i<1000;i++) { Hand hand1 = play1.nextHand(); Hand hand2 = play2.nextHand(); if(hand1.isStrongerThan(hand2)) { System.out.println("winner is "+play1); play1.win(); play2.lose(); }else if(hand2.isStrongerThan(hand1)) { System.out.println("winner is "+play2); play2.win(); play1.lose(); }else { System.out.println("even... "); play2.even(); play1.even(); } } } }
执行结果:
winner is [王五:0 ganmes,0 win, 0 lose ]
even...
even...
winner is [王五:3 ganmes,1 win, 0 lose ]
even...
even...
even...
winner is [王五:7 ganmes,2 win, 0 lose ]
winner is [王五:8 ganmes,3 win, 0 lose ]
winner is [王五:9 ganmes,0 win, 4 lose ]
winner is [王五:10 ganmes,4 win, 1 lose ]
winner is [王五:11 ganmes,1 win, 5 lose ]
winner is [王五:12 ganmes,5 win, 2 lose ]
winner is [王五:13 ganmes,2 win, 6 lose ]
even...
收藏文章数量从多到少与“把书读薄”是一个道理