设计模式学习笔记——策略(Strategy)模式
来源:互联网 发布:php导入excel到数据库 编辑:程序博客网 时间:2024/05/22 03:15
设计模式学习笔记——策略(Strategy)模式
@(设计模式)[设计模式, 策略模式, Stategy]
- 设计模式学习笔记策略Strategy模式
- 基本介绍
- 策略案例
- 类图
- 实现代码
- Hand类
- Strategy接口
- WinningStrategy类
- ProbStrategy类
- Player类
- 测试类
- 运行结果
- 策略模式中的角色
- Strategy策略
- ConcreteStrategy具体的策略
- Context上下文
- 类图
基本介绍
策略模式主要用于整体切换解决方案,算法。一般使用委托来实现。
策略案例
类图
实现代码
Hand类
package com.pc.strategy.example;/** * 猜拳手势类 * Created by Switch on 2017-02-20. */public class Hand { private static final int HANDVALUE_ST = 0; // 石头 private static final int HANDVALUE_JD = 1; // 剪刀 private static final int HANDVALUE_BU = 2; // 布 private int handValue; // 手势值 // 手势值对应的手势名 private static final String[] name = { "石头", "剪刀", "布" }; // 手势实例 public static final Hand[] hand = { new Hand(HANDVALUE_ST), new Hand(HANDVALUE_JD), new Hand(HANDVALUE_BU) }; /** * 构造方法,私有化,不能new出实例,注册表单例模式 * * @param handValue 手势值 */ private Hand(int handValue) { this.handValue = handValue; } /** * 根据手势值,获取手势实例 * * @param handValue 手势值 * @return 手势实例 */ public static Hand getHand(int handValue) { return hand[handValue]; } /** * 赢了返回true * * @param hand 手势实例 * @return */ public boolean isStrongerThan(Hand hand) { return fight(hand) == 1; } /** * 输了返回true * * @param hand 手势实例 * @return */ public boolean isWeakerThan(Hand hand) { return fight(hand) == -1; } /** * 比较 * * @param hand 手势实例 * @return */ private int fight(Hand hand) { if (this.handValue == hand.handValue) { return 0; // 平 } else if ((this.handValue + 1) % 3 == hand.handValue) { return 1; // 胜 } else { return -1; // 负 } } @Override public String toString() { // 手势值对应的手势名 return name[this.handValue]; }}
Strategy接口
package com.pc.strategy.example;/** * 猜拳策略接口 * Created by Switch on 2017-02-20. */public interface Strategy { /** * 下一个出拳手势 * * @return 手势实例 */ Hand nextHand(); /** * 根据上一次猜拳是否获胜,决定下一次的猜拳手势 * * @param win 是否获胜 */ void study(boolean win);}
WinningStrategy类
package com.pc.strategy.example;import java.util.Random;/** * Winning策略类 * Created by Switch on 2017-02-20. */public class WinningStrategy implements Strategy { private Random random; // 随机 private boolean won = false; // 上一把是否赢了 private Hand prevHand; // 上一把的手势对象 /** * 构造方法,传入初始化随机seek * * @param seed 随机种子 */ public WinningStrategy(int seed) { this.random = new Random(seed); } @Override public Hand nextHand() { if (!this.won) { this.prevHand = Hand.getHand(this.random.nextInt(3)); } return this.prevHand; } @Override public void study(boolean win) { this.won = win; }}
ProbStrategy类
package com.pc.strategy.example;import java.util.Random;/** * Prob策略类 * Created by Switch on 2017-02-20. */public class ProbStrategy implements Strategy { private Random random; // 随机 private int prevHandValue; // 上一把的手势值 private int currentHandValue; // 这一把的手势值 // 历史出拳概率数组 // history[上一把的手势值][这一把的手势值] 表示赢的次数 private int[][] history = { {1, 1, 1}, {1, 1, 1}, {1, 1, 1} }; /** * 构造方法,传入初始化随机seek * * @param seed 随机种子 */ public ProbStrategy(int seed) { this.random = new Random(seed); } @Override public Hand nextHand() { int randomValue = this.random.nextInt(this.getSum(this.currentHandValue)); int handValue = 0; if (randomValue < this.history[this.currentHandValue][0]) { // 当随机数在0到剪刀赢的次数时,赋值为0 handValue = 0; } else if (randomValue < this.history[this.currentHandValue][0] + this.history[this.currentHandValue][1]) { // 当随机数在剪刀赢的次数到石头赢得次数时,赋值为1 handValue = 1; } else { // 其他情况,赋值为2 handValue = 2; } // 当前值赋值为之前值 this.prevHandValue = this.currentHandValue; // 计算出来的值赋值为当前值 this.currentHandValue = handValue; return Hand.getHand(handValue); } /** * 获取history[上一把的手势值][三种手势]赢的总次数 * * @param hv 上一把的手势值 * @return history[上一把的手势值][三种手势]赢的总次数 */ 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[上一把的手势值][这一把的手势]赢的次数加一 this.history[this.prevHandValue][this.currentHandValue]++; } else { // history[上一把的手势值][其他手势]赢的次数加一 this.history[this.prevHandValue][(this.currentHandValue + 1) % 3]++; this.history[this.prevHandValue][(this.currentHandValue + 2) % 3]++; } }}
Player类
package com.pc.strategy.example;/** * 玩家类 * Created by Switch on 2017-02-20. */public class Player { private String name; // 玩家名 private Strategy strategy; // 策略对象 private int wincount; // 赢的次数 private int losecount; // 输出次数 private int gamecount; // 游戏总次数 /** * 构造方法 * * @param name 玩家名 * @param strategy 策略对象 */ public Player(String name, Strategy strategy) { this.name = name; this.strategy = strategy; } /** * 策略决定下次要出的手势 * * @return 手势对象 */ public Hand nextHand() { return this.strategy.nextHand(); } /** * 赢 */ public void win() { this.strategy.study(true); this.wincount++; this.gamecount++; } /** * 输 */ public void lose() { this.strategy.study(false); this.losecount++; this.gamecount++; } /** * 平 */ public void even() { this.gamecount++; } @Override public String toString() { return "[" + this.name + ":" + this.gamecount + " games, " + this.wincount + " win, " + this.losecount + " lose]"; }}
测试类
package com.pc.strategy.example.test;import com.pc.strategy.example.Hand;import com.pc.strategy.example.Player;import com.pc.strategy.example.ProbStrategy;import com.pc.strategy.example.WinningStrategy;import org.junit.Test;/** * Strategy Tester. * * @author Switch * @version 1.0 */public class StrategyTest { /** * 测试策略类 */ @Test public void testStrategy() { Player switchvov = new Player("switch", new WinningStrategy(54)); Player kity = new Player("kity", new ProbStrategy(32)); for (int i = 0; i < 10000; i++) { Hand nextValue1 = switchvov.nextHand(); Hand nextValue2 = kity.nextHand(); if (nextValue1.isStrongerThan(nextValue2)) { switchvov.win(); kity.lose(); System.out.println("Winner:" + switchvov); } else if (nextValue1.isWeakerThan(nextValue2)) { switchvov.lose(); kity.win(); System.out.println("Winner:" + kity); } else { System.out.println("Even..."); switchvov.even(); kity.even(); } } System.out.println("Total Result:"); System.out.println(switchvov); System.out.println(kity); }}
运行结果
Winner:[switch:1 games, 1 win, 0 lose]Winner:[switch:2 games, 2 win, 0 lose]Even...Winner:[kity:4 games, 1 win, 2 lose]Winner:[kity:5 games, 2 win, 2 lose]省略N行。。。Winner:[switch:9998 games, 3136 win, 3642 lose]Winner:[switch:9999 games, 3137 win, 3642 lose]Winner:[kity:10000 games, 3643 win, 3137 lose]Total Result:[switch:10000 games, 3137 win, 3643 lose][kity:10000 games, 3643 win, 3137 lose]
策略模式中的角色
Strategy(策略)
Strategy
角色负责决定实现策略所必需的接口(API
)。在案例中,由Strategy
接口扮演此角色。
ConcreteStrategy(具体的策略)
ConcreteStrategy
角色负责实现Strategy
角色的接口(API
) ,即负责实现具体的策略(战略、方向、方法和算法)。在案例中,由WinningStrategy
类和ProbStrategy
类扮演此角色。
Context(上下文)
负责使用Strategy
角色。Context
角色保存了ConcreteStrategy
角色的实例,并使用ConcreteStrategy
角色去实现需求(总之,还是要调用Strategy
角色的接口(API
))。在案例中,由Player
类扮演此角色。
类图
GitHub:DesignPatternStudy
——————参考《图解设计模式》
0 0
- 设计模式学习笔记——策略(Strategy)模式
- 设计模式学习笔记(三)—-Strategy策略模式
- 设计模式学习笔记(三)—Strategy策略模式
- 设计模式学习笔记--策略(Strategy)模式
- 设计模式学习—Strategy(策略)
- 设计模式——策略模式(Strategy) 笔记
- 设计模式学习——策略模式Strategy
- 设计模式学习—策略模式(Strategy Design Pattern)
- 设计模式——策略模式(Strategy)
- 设计模式——Strategy策略模式
- JAVA设计模式—策略模式(Strategy)
- java 设计模式学习笔记十五 strategy 策略设计模式
- 设计模式学习笔记(十八)——Strategy策略模式
- 设计模式学习笔记二十三(Strategy策略模式)
- 设计模式C++学习笔记之一(Strategy策略模式)
- 设计模式学习笔记(六)之策略模式(Strategy)
- 设计模式C++学习笔记之一(Strategy策略模式)
- 设计模式C++学习笔记之一(Strategy策略模式)
- Spring MVC 学习笔记 json格式的输入和输出
- 显示Gralloc模块分配内存(buffer_handle_t、private_handle_t数据结构的关系)
- 实现键盘记录的e.Whick和keyCode
- DOM对象与Jquery对象的区分
- python的本地变量,全局变量,函数的作用域,嵌套函数引用包装函数
- 设计模式学习笔记——策略(Strategy)模式
- spark 开发考题!面试题! 根据IP地址查询归属地,统计归属地IP地址数
- 22-TCP 协议(PSH 标志)
- 树回归
- Jquery基础总结。。。
- mysql limit 优化
- tensorflow学习math_ops(一)
- JQuery插件开发 + 插件
- 【Linux】Centos6.8安装rabbitmq