Strategy - 策略模式

概述:

整体替换算法的实现部分(最简单的例子:加减乘除,或者switch)

Strategy_sample


说明:

1.本文仅仅是对 图解设计模式 的简单总结(个人笔记).
2.文章中的图片均来自本书,添加水印只是为了防止盗链行为,并无侵权的想法.
综上,若侵权, 请联系删除!
转载请标注出处!


案例:

  • 案例说明:

    让电脑玩猜拳游戏,通过两种不同的策略实现猜拳,第一种策略是,”如果本局胜利,这下局出一样的手势”,第二种策略:”根据上一局的策略计算出下一句的手势”

  • Strategy_uml_case

  • 主要代码:

  • ProbStrategy.java(第二种策略)

    package Gof.Strategy;
    
    import java.util.Random;
    
    public class ProbStrategy implements Strategy {
        private Random random;
        private int prevHandValue = 0;
        private int currentHandValue = 0;
        private int[][] history = {
            { 1, 1, 1, },
            { 1, 1, 1, },
            { 1, 1, 1, },
        };
        public ProbStrategy(int seed) {
            random = new Random(seed);
        }
        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;
            }
            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;
        }
        public void study(boolean win) {
            if (win) {
                history[prevHandValue][currentHandValue]++;
            } else {
                history[prevHandValue][(currentHandValue + 1) % 3]++;
                history[prevHandValue][(currentHandValue + 2) % 3]++;
            }
        }
    }
    
  • Player.java

    package Gof.Strategy;
    
    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++;
        }
        public String toString() {
            return "[" + name + ":" + gamecount + " games, " + wincount + " win, " + losecount + " lose" + "]";
        }
    }
    
  • 代码链接:传送门

    uml综述Strategy_uml

  • Strategy: 决定实现车旅所必须的API

  • ConcreteStrategy:实现strategy定义的接口

  • Context: Context保存了ConcreteStrategy角色实例,并用ConcreteStrategy角色去实现需求(调用接口)

收获:

  • strategy特意将算法与其他部分分离开来,只是定义了与算法相关的api,然后在程序中用委托(定义strategy对象)的方式使用算法.
  • 使用委托这种弱关联关系可以很方便的整体替换算法

相关设计模式:

  • FlyWeight: Flyweight可以让多个地方共享concretestrategy角色
  • Abstract Factory: 可以整体的替换具体工厂,零件,和产品
  • State: concreteStrate 是表示状态的类,在state中,每次状态改变时,被委托对象都必定会被替换
  • Strategy: concretestrategy 表示算法的类,可以替换被委托对象的类,当然如果没有必要,也可以不替换

注意:

此部分内容属于对GOF Design Pattern知识的初步认知阶段,参考书籍是结城浩的《图解设计模式》,简单易懂,十分推荐!
以上内容,作者一字一句码出来的,纯属不易,欢迎大家转载,转载是还请您表明出处。另外如果我有侵权行为,请在下方留言,确认后我会及时撤销相应内容,谢谢大家!

PS:欢迎大家来到我的小站,鸣谢!