图解设计模式 - Strategy 模式
2017-12-08 21:48
246 查看
读书笔记 仅供参考
策略模式
策略模式就是可以整体地替换算法,可以轻松地以不同的算法去解决同一个问题。角色和 UML
Strategy
负责决定实现策略(算法)哦接口(API)ConcreteStrategy
负责实现 Strategy 定义的接口(API)Context
负责使用 Strategy 角色UML
例子
例程是一个猜拳的程序,有两种猜拳策略,一是上一局赢了就不变手,输了就随机出,二是根据之前所有的出拳结果统计概率出拳。//出拳手势 public class Hand { public static final int HANDVALUE_GUU = 0;//代表石头 public static final int HANDVALUE_CHO = 1;//代表剪刀 public static final int HANDVALUE_PAA = 2;//代表步 public static final Hand[] hand = { new Hand(HANDVALUE_GUU), new Hand(HANDVALUE_CHO), new Hand(HANDVALUE_PAA) }; private static final String[] name = { "石头", "剪刀", "布" }; private int handValue;//猜拳中出的值 private Hand(int handValue) { this.handValue = handValue; } public static Hand getHand(int handValue) { return hand[handValue]; } //判断是否强于对方 public boolean isStrongerThan(Hand hand) { return fight(hand) == 1; } //判断是否弱于对方 public boolean isWeakerThan(Hand hand) { return fight(hand) == -1; } private int fight(Hand hand) { if(this == hand) { return 0; } else if((this.handValue + 1) % 3 == hand.handValue) { return 1; } else { return -1; } } @Override public String toString() { return name[handValue]; } }
public interface Strategy { Hand nextHand(); //根据上一局输赢进行学习 void study(boolean win); }
public class WinningStrategy implements Strategy { //如果上一局获胜,就和上一局出相同的 //如果上一局失败,随机出 //随机值,决定怎么出 private Random random; //上一局的结果 private boolean won = false; //上一局的手势 private Hand prevHand; public WinningStrategy(int seed) { this.random = new Random(seed); } @Override public Hand nextHand() { if(!won) { prevHand = Hand.getHand(random.nextInt(3)); } return prevHand; } @Override public void study(boolean win) { won = win; } }
public class ProbStrategy implements Strategy { //根据之前的猜拳结果概率决定 private Random random; private int prevHandValue = 0; private int currentHandValue = 0; //history[上一局出的手势][这一局可能出的手势] 代表胜利的次数 private int[][] history = { {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, }; public ProbStrategy(int seed) { random = new Random(seed); } @Override public Hand nextHand() { int bet = random.nextInt(getSum(currentHandValue)); int handValue = 0; if(bet < history[currentHandValue][0]) { handValue = 0; } else if (bet < history[currentHandValue][1]) { handValue = 1; } else { handValue = 2; } prevHandValue = currentHandValue; currentHandValue = handValue; return Hand.getHand(handValue); } private int getSum(int hv) { int sum = 0; for(int i = 0; i < 3; i++) { sum += history[hv][i]; } return sum; } @Override public void study(boolean win) { if(win) { history[prevHandValue][currentHandValue]++; } else { history[prevHandValue][(currentHandValue + 1) % 3]++; history[prevHandValue][(currentHandValue + 2) % 3]++; } } }
//选手,有姓名,策略,统计输赢 public class Player { private String name; private Strategy strategy; private int winCount; private int loseCount; private int gameCount; public Player(String name, Strategy strategy) { this.name = name; this.strategy = strategy; } public Hand nextHand() { return strategy.nextHand(); } public void win() { strategy.study(true); winCount++; gameCount++; } public void lose() { strategy.study(false); loseCount++; gameCount++; } public void even() { gameCount++; } @Override public String toString() { return "Player{" + "name='" + name + '\'' + ", winCount=" + winCount + ", loseCount=" + loseCount + ", gameCount=" + gameCount + '}'; } }
public class Main { //生成两个选手,采取不同的策略 public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int seed1 = scanner.nextInt(); int seed2 = scanner.nextInt(); Player player1 = new Player("Taro", new WinningStrategy(seed1)); Player player2 = new Player("Hana", new ProbStrategy(seed2)); for(int i = 0; i < 10000; i++) { Hand nextHand1 = player1.nextHand(); Hand nextHand2 = player2.nextHand(); if(nextHand1.isStrongerThan(nextHand2)) { System.out.println("Winner: " + player1); player1.win(); player2.lose(); } else if(nextHand2.isStrongerThan(nextHand1)) { System.out.println("Winner: " + player2); player2.win(); player1.lose(); } else { System.out.println("Even"); player1.even(); player2.even(); } } System.out.println("Total result: "); System.out.println(player1.toString()); System.out.println(player2.toString()); } }
UML
PS
策略模式使动态替换成为了可能。相关文章推荐
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- [设计模式] 21 策略模式 Strategy
- 设计模式-策略模式---Strategy(对象行为型)
- 设计模式之策略模式-strategy
- 设计模式(4)-行为型-策略模式(Strategy)
- 设计模式-Strategy模式戏说
- 05-面向对象(单例设计模式-内存图解). 06-面向对象(单例设计模式-懒汉式).
- Head First 设计模式 C++实现-Strategy(策略模式)
- java设计模式之 strategy策略模式
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- 设计模式之策略Strategy模式
- 二十三种设计模式图解
- 23种设计模式之python实现--Strategy模式
- 设计模式之Strategy(策略)
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- 23设计模式之策略模式(Strategy)
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- 设计模式1--策略模式(the strategy design pattern)
- [GoF设计模式]Proxy模式和Strategy模式的C++实现
- JAVA与设计模式--之STRATEGY策略模式