策略模式

  策略模式是指定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也就是说这些算法所完成的功能一样,对外的接口一样,只是各自实现上存在差异。用策略模式来封装算法,效果比较好。

优点:

  1、 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
  2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
  3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

缺点:
  1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
  2、 在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象

以CS里的人物作为例子,每个人都可以有几个武器,武器之间动态切换,武器拥有统一的攻击命令,首先给出替换算法的定义:

//抽象接口
class WeaponBehavior
{
public:
virtual void useWeapon() = ;
};
//三种具体的替换算法
class AK47 : public WeaponBehavior
{
public:
void useWeapon() { cout<< "Use AK47 to shoot!" <<endl; }
}; class Knife : public WeaponBehavior
{
public:
void useWeapon() { cout<< "Use Knife to kill!" <<endl; }
};
class Rifle : public WeaponBehavior
{
public:
void useWeapon() { cout<< "Use Rifle to shoot!" <<endl; }
};

接着给出角色Character的定义,这里很关键,Character的实现方式直接影响了用户的使用方式,其关键在于如何指定替换算法。

方式一

直接通过参数指定,传入一个特定算法的指针:

//Character需要用到替换算法
class Character
{
public:
Character() { weapon = ; }
void setWeapon(WeaponBehavior *w)
   {
     this->weapon = w;
   }
void virtual fight() = ; protected:
WeaponBehavior *weapon;
}; class King:public Character
{
public:
void fight()
{
if ( this->weapon == NULL)
     {
        cout << "You don't have a weapon! Please Set Weapon!" << endl;
     }
else
     {
       weapon->useWeapon();
     }
}
}; int main()
{
Character *kin = new King();
kin->fight();

WeaponBehavior *ak47 = new AK47();
kin->setWeapon(ak47); //暴露了算法的定义
kin->fight();     if(kin) delete kin;
return ;
}

方式二

也是直接通过参数指定,只不过不是传入指针,而是一个标签。这样用户只要知道算法的相应标签即可,而不需要知道算法的具体定义。

//Character需要用到替换算法
enum WEAPON {WEAPON_AK, WEAPON_KNIFE, WEAPON_RIFLE}; //标签
class Character
{
public:
Character() { weapon = ; }
void setWeapon(enum WEAPON w)
{
if(w == WEAPON_AK) weapon = new AK47();
else if(w == WEAPON_KNIFE) weapon = new Knife();
else if(w == WEAPON_RIFLE) weapon = new Rifle();
else weapon = NULL;
}
void virtual fight() = ; protected:
WeaponBehavior *weapon;
}; class King:public Character
{
public:
void fight()
{
if ( this->weapon == NULL)
{
cout << "You don't have a weapon! Please Set Weapon!" << endl;
}
else
{
weapon->useWeapon();
}
}
}; int main()
{
Character *kin = new King();
kin->fight(); kin->setWeapon(WEAPON_AK);
kin->fight(); if(kin) delete kin;
return ;
}

相比方式一,这种方式用起来方便多了。其实这种方式将简单工厂模式与策略模式结合在一起,算法的定义使用了策略模式,而Character的定义其实使用了简单工厂模式。

出处: http://blog.csdn.net/wuzhekai1985

设计模式 --> (3)策略模式的更多相关文章

  1. 设计模式:策略模式(Strategy)

    定   义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...

  2. PHP设计模式之策略模式

    前提: 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查 找.排序等,一种常用的方法是硬编码(Hard Cod ...

  3. JavaScript设计模式之策略模式(学习笔记)

    在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...

  4. 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)

    原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...

  5. JavaScript设计模式之策略模式

    所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...

  6. 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查

    原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...

  7. [design-patterns]设计模式之一策略模式

    设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不 ...

  8. 设计模式入门,策略模式,c++代码实现

    // test01.cpp : Defines the entry point for the console application.////第一章,设计模式入门,策略模式#include &quo ...

  9. 设计模式之策略模式和状态模式(strategy pattern & state pattern)

    本文来讲解一下两个结构比较相似的行为设计模式:策略模式和状态模式.两者单独的理解和学习都是比较直观简单的,但是实际使用的时候却并不好实践,算是易学难用的设计模式吧.这也是把两者放在一起介绍的原因,经过 ...

  10. python设计模式之策略模式

    每次看到项目中存在大量的if else代码时,都会心生一丝不安全感. 特别是产品给的需求需要添加或者更改一种if条件时,生怕会因为自己的疏忽而使代码天崩地裂,哈哈,本文的目的就是来解决这种不安全感的, ...

随机推荐

  1. WIN2003+IIS6+FastCGI+PHP5.3的安装配置

    本文所用的软件的下载地址 fastcgi的下载地址:http://download.microsoft.com/download/E/0/C/E0C0709A-66E5-4113-9A6C-A5F65 ...

  2. 错误代码: 1054 Unknown column 't.createUsrId' in 'group statement'

    1.错误描述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:select count(t.id),t.`createUserId` fr ...

  3. 7.C++类与封装的概念

    类通常分为以下两部分 -类的内部具体实现 -类的外部使用方法 比如: 用户使用手机,只需要知道如何使用. 而手机开发者,则需要考虑手机内部的实现细节. 类的封装 并不是类的每个成员变量和成员函数都要对 ...

  4. Java冒泡排序法升级版

    /*  * 冒泡排序之升级版,可比较整型数组.小数型数组  *   * */ public static <T extends Comparable<T>> void Bubb ...

  5. 关于spring事务注解实战

    1.概述 spring的事务注解@Transaction 相信很多人都用过,而@Transaction 默认配置适合80%的配置. 本篇文章不是对spring注解事务做详细介绍,而是解决一些实际场景下 ...

  6. java继承属性相关介绍

    这个只需要记住一点,父类的任何属性(变量可以看做属性),子类均可继承并覆盖,allType(father)-->changeAnyType(son)-->AnyType 这是父类的所有代表 ...

  7. 在VCS仿真器中使用FSDB

    FSDB(Fast Signal Database)是Verdi支持的文件格式,用于保存仿真产生的信号波形.据Verdi文档说明,FSDB比标准的VCD格式节省磁盘空间,处理速度更快.要用VCS仿真器 ...

  8. NOIP2011题解

    NOIP2011其实早就做完了....一直懒得写.... Day1 T1铺地毯 我什么都不想说,不会做您就没必要接着看了.... #include<iostream> using name ...

  9. [Luogu4175][CTSC2008]网络管理Network

    又是权限题qwq 一句话题意:带修改树上路径第k大 sol 数据结构?还是再见吧.学一手合格的整体二分,只有思维强大,才能见题拆题. 如果你做过整体二分的动态区间第k大就会发现这是一样的题. 无非是区 ...

  10. TP5模型关联问题

    在使用模型关联时:假如有表   merchant商户表   m_store 店铺表  m_store_ref 商户店铺关联表  user 普通用户表 $mer = Merchant::with([ ' ...