理解策略模式

  策略模式定义了算法族,不同的策略实现之间可以互相替换,让算法的变化独立于使用算法的客户。
这里的算法可以理解为对传入参数的处理或者某种行为。例如:如下java代码,对字符串实现不同的比较策略,Formatter类与CompareStrategy策略接口相依赖。可以使自身能够有对字符串的不同处理。

public interface CompareStrategy {
    boolean less(String str1, String str2);
}

public class SizeCmpStrategy implements CompareStrategy {
    @Override
    public boolean less(String str1, String str2) {
        return str1.length() < str2.length();
    }
}

public class IgnoreCaseCmpStrategy implements CompareStrategy {
    @Override
    public boolean less(String str1, String str2) {
        return str1.compareToIgnoreCase(str2) < 0;
    }
}

public class Formatter {
    private CompareStrategy cmp;

    public CompareStrategy getCmp() {
        return cmp;
    }

    public void setCmp(CompareStrategy cmp) {
        this.cmp = cmp;
    }
}

  通常可以通过继承,重写父类的方法,使不同子类具有多态的行为。策略模式可以提供了替代继承的另一种方法。如果我们需要具备不同功能的类,我们可以不必总是通过继承某一父类实现不同的行为。而是通过注入不同的Strategy使其可以具备不同的行为。再举一个例子:

在一个游戏的角色随着升级的过程中,不同等级的英雄有不同的攻击和防守。可以将这变化的攻击和防守进行封装。如下面的Java代码:

public interface Attack {
    void attack();
}

public interface Defend {
    void defend();
}

public class PrimaryAttack implements Attack {
    @Override
    public void attack() {
        System.out.println("初级进攻");
    }
}

public class PrimaryDefend implements Defend {
    @Override
    public void defend() {
        System.out.println("初级防守");
    }
}

public class SeniorAttack implements Attack {
    @Override
    public void attack() {
            System.out.println("高级进攻");
    }
}

public class SeniorDefend implements Defend {
    @Override
    public void defend() {
        System.out.println("高级防守");
    }
}
public class Hero {
    private Attack attack;

    public Attack getAttack() {
        return attack;
    }

    public void setAttack(Attack attack) {
        this.attack = attack;
    }

    private Defend defend;

    public Defend getDefend() {
        return defend;
    }

    public void setDefend(Defend defend) {
        this.defend = defend;
    }

    public void doAttack() {
        attack.attack();
    }

    public void doDefend() {
        defend.defend();
    }
    public static void main(String[] args){
        Hero hero=new Hero();
        hero.setAttack(new PrimaryAttack());
        hero.setDefend(new PrimaryDefend());
        hero.doAttack();
        hero.doDefend();
        System.out.println("升级啦");
        hero.setAttack(new SeniorAttack());
        hero.setDefend(new SeniorDefend());
        hero.doAttack();
        hero.doDefend();
    }
}

//程序输出:
/*
初级进攻
初级防守
升级啦
高级进攻
高级防守
*/

  由上述的例子,我们可以得出策略模式优点:这是一种可以替代继承的方法。并且这种行为是可以动态改变的并且不像继承一样硬编码。

2. C++模板和策略模式

  上述Java实现,C++可以很方便的进行类似的实现。这里再介绍一下基于C++模板的策略模式实现。

  C++的模板编程可以作为另外一种策略模式的实现,并且可能是更好的实现。将Strategy作为模板参数,开发出更为方便(隐式接口),高效率(编译期绑定)的程序。如:

#include <iostream>

class PrimaryAttack{
public:
    void attack(){
        std::cout<<"进行初级进攻"<<std::endl;
    }
};
class PrimaryDefend{
public:
    void defend(){
        std::cout<<"进行初级防守"<<std::endl;
    }
};
class SeniorDefend{
public:
    void defend(){
        std::cout<<"进行高级防守"<<std::endl;
    }
};
class SeniorAttack{
public:
    void attack(){
        std::cout<<"进行高级进攻"<<std::endl;
    }
};

template<typename Attack, typename Defend>
class Hero{
public:
    Hero():attack(),defend(){}
    void doAttack()
    {
        attack.attack();
    }
    void doDefend(){
        defend.defend();
    }

private:
    Attack attack;
    Defend defend;
};
int main(){
    std::cout<<"我是初级英雄"<<std::endl;
    Hero<PrimaryAttack, PrimaryDefend> primary_hero;
    primary_hero.doAttack();
    primary_hero.doDefend();
    std::cout<<"我是高级英雄"<<std::endl;
    Hero<SeniorAttack, SeniorDefend> senior_hero;
    senior_hero.doAttack();
    senior_hero.doDefend();
}

//程序输出:
/*
我是初级英雄
进行初级进攻
进行初级防守
我是高级英雄
进行高级进攻
进行高级防守
*/

Note:由于模板属于编译时多态,因此行为属于编译期绑定,不能像之前Java实现那样对策略进行动态的改变。

  使用模板实现策略模式,带来了代码的简洁,不再需要定义接口,再进行实现。由于C++模板编程隐式接口约定,因此需要以文档的形式对策略的设计进行规定,如规定 Attack, Defend类型参数必须实现attack(),defend()方法。

与基于C++模板的策略模式相比,Java的实现比较繁琐,基于C++模板的实现更为轻量级。

时间: 2024-10-03 06:48:11

理解策略模式的相关文章

用最简单的例子理解策略模式(Strategy Pattern)

当一个动作有多种实现方法,在实际使用时,需要根据不同情况选择某个方法执行动作,就可以考虑使用策略模式. 把动作抽象成接口,比如把玩球抽象成接口. public interface IBall { void Play(); } 有可能是玩足球.篮球.排球等,把这些球类抽象成实现接口的类. public class Football : IBall { public void Play() { Console.WriteLine("我喜欢足球"); } } public class Bas

用最简单的例子理解对象为Null模式(Null Object Pattern)

所谓的"对象为Null模式",就是要求开发者考虑对象为Null的情况,并设计出在这种情况下的应对方法. 拿"用最简单的例子理解策略模式(Strategy Pattern) "中的例子来说,在我们的客户端程序中只考虑了用户输入1,2,3的情况,如果用户输入其它数字,比如4,就没有一个对应的IBall接口实现类实例产生,于是会报如下的错: 为了应对这种情况,我们专门设计一个类,当用户输入1,2,3以上的数字,就产生该类的实例.该类同样实现IBall接口. public

c++策略模式

这几天需要学习一下设计模式来为设计代码结构使得代码可扩展性强,代码更加易于维护,不用想很长时间也不知道怎么去设计一个工具的代码. 我的理解策略模式: 1.有一个策略基类,策略类是什么呢?策略类就是一个算法类,每一个算法都有一个类.下面的例子便于理解这个 例子: 你是设计师,空调有暖风.冷风.没风三种模式,那么如何为空调设计这个应用程序呢?且以后还要扩展其他模式? 这时候使用策略模式是最好的了,三种策略类(暖风策略类,冷风策略类,没风策略类) 2.三种类都继承与基类,每一个策略类中有一个方法用于实

IOS之Objective-C学习 策略模式

对于策略模式,我个人理解策略模式就是对各种规则的一种封装的方法,而不仅仅是对算法的封装与调用而已.与工厂模式中简单工厂有点类似,但是比简单工厂更有耦合度,因为策略模式以相同的方法调用所有的规则,减少了规则类和规则类之间的耦合度. 接下来我用策略模式编辑代码来计算斗地主中地主根据坐庄成功失败翻倍情况的得分情况. 创建一个分数类 Score.h #import <Foundation/Foundation.h> #define BASIC_POINT 10 @interface Score : N

理解javascript中的策略模式

策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效的避免很多if条件语句. 2. 策略模式提供了开放-封闭原则,使代码更容易理解和扩展. 3. 策略模式中的代码可以复用. 一:使用策略模式计算奖金: 下面的demo是我在书上看到的,但是没有关系,我们只是来理解下策略模式的使用而已,我们可以使用策略模式来计算奖金问题: 比如公司的年终奖是根据员工的工资和绩效来考核的,绩效为A的人,年终奖

深入理解JavaScript系列(33):设计模式之策略模式(转)

介绍 策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户. 正文 在理解策略模式之前,我们先来一个例子,一般情况下,如果我们要做数据合法性验证,很多时候都是按照swith语句来判断,但是这就带来几个问题,首先如果增加需求的话,我们还要再次修改这段代码以增加逻辑,而且在进行单元测试的时候也会越来越复杂,代码如下: validator = { validate: function (value, type) { switch (type) { c

Head First 设计模式之一 策略模式

策略模式 定义 策略模式定义了算法族,分别封装起来,让他们之间可以相互转换,此模式让算法的变化独立于使用算法的客户. 实例 上面的定义看起来说的不太清楚,记定义无意义,理解策略模式还是要看书中的鸭子例子.假设设计一个模拟鸭子的游戏,鸭子的种类有很多,有红头鸭.绿头鸭等等,鸭子可以划水,可以呱嘎叫.在这个模拟游戏的实现上,自然会想到用继承的方法,定义一个鸭子基类,具体的鸭子类型继承自鸭子基类.如下图所示 所有鸭子都会飞.呱呱叫和游泳,这些功能由基类来实现,display函数用来输出鸭子实例的类型,

深入理解JavaScript系列(33):设计模式之策略模式

介绍 策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户. 正文 在理解策略模式之前,我们先来一个例子,一般情况下,如果我们要做数据合法性验证,很多时候都是按照swith语句来判断,但是这就带来几个问题,首先如果增加需求的话,我们还要再次修改这段代码以增加逻辑,而且在进行单元测试的时候也会越来越复杂,代码如下: validator = { validate: function (value, type) { switch (type) { c

设计模式 策略模式 以角色游戏为背景

今天不想写代码,给大家带来一篇设计模式的文章,帮助大家可以把系统组织成容易了解.容易维护.具有弹性的架构. 先来看看策略模式的定义: 策略模式(Strategy Pattern):定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户. 好了,对于定义,肯定不是一眼就能看明白的,不然这篇文章就收尾了,对于定于大家简单扫一眼,知道个大概,然后继续读下面的文章,读完以后再来回味,效果嘎嘣脆.大家应该都玩过武侠角色游戏,下面我就以角色游戏为背景,为大家介绍:假设公司需