策略模式(Strategy

Strategy

无论什么程序,其目的都是解决问题。而为了解决问题,我们又需要编写特定的算法。使用Strategy模式可以整体地替换算法的实现部分。能够整体地替换算法,能让我们轻松地以不同的算法去解决同一个问题,这种模式就是Strategy模式。(整体替换算法)

理清职责

  • |名字|说明
    |Hand表示猜拳游戏中的“手势”的类
    |strategy|表示猜拳游戏中的策略的类
    |Winningstrategy |表示“如果这局猜拳获胜,那么下一局也出一样的手势”这一策略的类表示“根据上一局的手势从概率上计算出下一局的手势从之前的猜拳结果计算下一局|
    |Probstrategy出各种拳的概率”这一策略的类
    |Player表示进行猜拳游戏的选手的类
    |Main测试程序行为的类
  • 具体说明
  1. 比如C++ 的STL 的Sort 以及在Java中Arrays.sort()都是可以使用策略模式来根据情况构造解决办法的
  2. 如果使用Strategy模式,在程序运行中也可以切换ConcreteStrategy角色。例如,在内存容量少的运行环境中可以使用slowButLessMemoryStrategy(速度慢但省内存的策略),而在内存容量多的运行环境中则可以使用FastButMoreMemorystrategy(速度快但耗内存的策略)。

UML

Code

  • Hand:
public class Hand {

    // 石头
    private static final int HANDVALUE_GUU=0;
    // 剪刀
    private static final int HANDVALUE_GHO=1;
    // 布
    private static final int HANDVALUE_PAA=2;

    private static final Hand[] HANDS=new Hand[]{
            new Hand(HANDVALUE_GUU),
            new Hand(HANDVALUE_GHO),
            new Hand(HANDVALUE_PAA),
    };

    public static final  String name[]={
            "石头","剪刀","布"
    };

    private int handvalue;

    public Hand(int handvalue) {
        this.handvalue = handvalue;
    }

    public static Hand getHand(int handvalue){
        return HANDS[handvalue];
    }

    // 胜利
    public boolean isStrongerThan(Hand hand){
        return fight(hand)==1;
    }

    // 战败
    public boolean isWeakerThan(Hand hand){
        return fight(hand)==-1;
    }

    /**
     * 计分: 平 0 胜1 负 -1
     * @param hand
     * @return
     */
    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[this.handvalue];
    }
}
  • Player
public class Player {

    private String name;

    private Strategy strategy;

    private int wincount;
    private int losrcount;
    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);
        gamecount++;
        wincount++;
    }

    public void lose(){
        strategy.study(false);
        losrcount++;
        gamecount++;
    }

    public void even(){
        gamecount++;
    }

    @Override
    public String toString() {
        return "Player{" +
                "wincount=" + wincount +
                ", losrcount=" + losrcount +
                ", gamecount=" + gamecount +
                '}';
    }
}
  • ProbStrategy
public class ProbStrategy implements Strategy {

    private Random random;

    public ProbStrategy(int seed) {
        this.random=new Random(seed);
    }

    private int pevHandValue=0;

    private int currentHandValue=0;

    private int [] [] history=new int[][]{
            {1,1,1},
            {1,1,1},
            {1,1,1}
    };

    /**
     * 如果该随机数在0至3(不含3)之间,那么出石头
     * 如果该随机数在3至8(不含8)之间,那么出剪刀
     * 如果该随机数在8至15(不含15)之间,那么出布
     * @return
     */
    @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][0]+history[currentHandValue][1])){
            handValue=1;
        }else {
            handValue=2;
        }
        pevHandValue=currentHandValue;
        currentHandValue=handValue;
        return Hand.getHand(handValue);
    }

    private int getSum(int currentHandValue) {
        int sum=0;
        for (int i = 0; i < 3; i++) {
            sum+=history[currentHandValue][i];
        }
        return sum;
    }

    @Override
    public void study(boolean win) {
        if(win){
            history[pevHandValue][currentHandValue]++;
        }else{
            history[pevHandValue][(currentHandValue+1)%3]++;
            history[pevHandValue][(currentHandValue+2)%3]++;
        }
    }
}
  • Strategy
public interface Strategy {

    /**
     * nextHand方法的作用是“获取下一局要出的手势”。调用该方法后,
     * 实现了strategy接口的类会绞尽脑汁想出下一局出什么手势。
     * @return
     */
    Hand nextHand();

    /**
     *study方法的作用是学习“上一局的手势是否获胜了”。
     * 如果在上一局中调用nextHand方法获胜了,就接着调用study(true);
     * 如果输了,就接着调用study(false)。这样,Strategy接口的实现类就会改变自己的内部状态,
     * 从而为下一次nextHand被调用时究竟是返回“石头”“剪刀”还是“布”提供判断依据。
     * @param win
     */
    void study(boolean win);
}
  • Winningstrategy

public class Winningstrategy implements Strategy {

    private Random random;
    // 存储上一局状态

    private boolean won=false;

    private Hand preHand;

    /**
     * 有预见性的随机数种子
     * @param seed
     */
    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 MainT {

    public static void main(String[] args) {

        Player tom = new Player("tom", new Winningstrategy(2));
        Player cat = new Player("cat", new ProbStrategy(3));

        for (int i = 0; i < 100; i++) {
            Hand hand = tom.nextHand();
            Hand hand1 = cat.nextHand();
            if(hand.isStrongerThan(hand1)){
                System.out.println("tom is win");
                tom.win();
                cat.lose();
            }else if(hand1.isStrongerThan(hand)){
                System.out.println("cat is win");
                cat.win();
                tom.lose();
            }else{
                System.out.println("Even----");
                cat.even();
                tom.even();
            }
        }
        System.out.println(tom);
        System.out.println(cat);

    }
}

原文地址:https://www.cnblogs.com/dgwblog/p/9827537.html

时间: 2024-08-28 08:58:34

策略模式(Strategy的相关文章

设计模式之策略模式(Strategy)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

策略模式(Strategy Pattern)

策略模式(Strategy Pattern) 抛开晦涩的定义,首先看一个例子: 我们想要创建一个模拟鸭子的游戏,在这个游戏中,会有各种类型的鸭子,比如mallard duck,red head duck,rubber duck(除了rubber duck(橡皮鸭),看见这其余两种鸭子很好奇,于是查找相关图片,发现mallard duck是绿头鸭,red head duck是红头鸭,自己生活中还没有见过,有趣,哈哈!三种鸭子图片如下所示). 回归话题,在这个模拟鸭子的游戏中,各种鸭子均有两种能力,

设计模式 - 策略模式(Strategy Pattern) 具体解释

策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全部, 禁止转载, 如有须要, 请站内联系. 策略模式: 定义了算法族, 分别封装起来, 让它们之间能够相互替换, 此模式让算法的变化独立于使用算法的客户. 对于父类的子类族须要常常扩展新的功能, 为了使用父类比較灵活的加入子类, 把父类的行为写成接口(interface)的形式; 使用set()方法

设计模式 ( 十八 ) 策略模式Strategy(对象行为型)

设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕该功能.如查找.排序等,一种经常使用的方法是硬编码(Hard Coding)在一个类中,如须要提供多种查找算法,能够将这些算法写到一个类中,在该类中提供多个方法,每个方法相应一个详细的查找算法:当然也能够将这些查找算法封装在一个统一的方法中,通过if-else-或者case等条件推断语句来进行选择.

设计模式 - 策略模式(Strategy Pattern) 详解

策略模式(Strategy Pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权所有, 禁止转载, 如有需要, 请站内联系. 策略模式: 定义了算法族, 分别封装起来, 让它们之间可以相互替换, 此模式让算法的变化独立于使用算法的客户. 对于父类的子类族需要经常扩展新的功能, 为了使用父类比较灵活的添加子类, 把父类的行为写成接口(interface)的形式; 使用set()方法,

设计模式实现C++ --策略模式Strategy(对象行为型)

1.问题 出行旅游:我们可以有几个策略可以考虑:可以骑自行车,汽车,做火车,飞机.每个策略都可以得到相同的结果,但是它们使用了不同的资源.选择策略的依据 是费用,时间,使用工具还有每种方式的方便程度. 2.解决方案 策略模式:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化. 策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性的思想. strategy模式类图: 3.应用场景 1. 

设计模式---策略模式Strategy(对象行为型)

1. 概述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理. 2. 应用场景 (1)多个类只区别在表现行为不同,在运行时动态选择具体要执行的行为. (2)需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现. (3)对客户隐藏具体策略(算法)的实现细节,彼此完全独立. 3. 示例 出行旅游:我们可以有几个策略可以考虑:可

如何让孩子爱上设计模式 ——14.策略模式(Strategy Pattern)

如何让孩子爱上设计模式 --14.策略模式(Strategy Pattern) 描述性文字 本节讲解的是行为型设计模式中的第一个模式: 策略模式, 这个模式非常简单,也很好理解. 定义一系列的算法,把每个算法封装起来,并使得他们可以相互替换, 让算法独立于使用它的客户而变化. 一般用来替换if-else,个人感觉是面向过程与面向对象思想的 过渡,这里举个简易计算器的栗子,帮助理解~ 普通的if-else/switch计算器 普通的面向过程if-else简易计算器代码如下: 运行结果如下: 这里我

设计模式--策略模式(strategy)

1.策略模式(strategy ['stræt?d?i]) 我的理解是:方案候选模式 (反正关键就是有很多的候选,哈哈) 看了很多例子,都是在说鸭子的,那个例子很好,然后我就照葫芦画瓢了, 他们生产鸭子,我们就制造人 所以,父类 Person类就出来了 1 public abstract class Person { 2 //唱歌可就不一样了,唱法不同,唱功不同:而且哑巴不能唱歌 3 public void singing(){ 4 System.out.println("我要唱歌")

说说设计模式~策略模式(Strategy)

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.而对于客户端(UI)来说,可以通过IOC再配合工厂模块,实现动态策略的切换,策略模块通常于一个抽象策略对象(interface or abstract class),多个具体策略对象(implement class )和一个调用策略的入口组成. 何时能用到它? 对于UI来说,可能一个功能会有多种实现方式,而且实现方式可能还会有扩展,例如,一个ATM机,它目前支持工行,建行,家行,以后可能又出现了占占银行,而这时,ATM