策略模式

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

优点:

  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. Netty的并发编程实践2:volatile的正确使用

    长久以来大家对于volatile如何正确使用有很多的争议,既便是一些经验丰富的Java设计师,对于volatile和多线程编程的认识仍然存在误区.其实,volatile的使用非常简单,只要理解了Jav ...

  2. ReferenceError: Error #1065: 变量 dataGridArray 未定义

    1.错误描述 ReferenceError: Error #1065: 变量 dataGridArray 未定义. at global/flash.utils::getDefinitionByName ...

  3. nested exception is java.sql.SQLException: IO 错误

    1.错误描述 (mx.messaging.messages::ErrorMessage)#0 body = (null) clientId = "18CE3B03-9709-9DA8-763 ...

  4. sqlserver 以年月日为条件查询记录

    今天做一个东西的时候,要查某年,某月的记录,从网上找到了sqlserver中的datepart函数,该函数是用来提取年份,月份,日期的一个函数,带两个参数,第一个为(yy,mm,dd)其中一个,表示年 ...

  5. java查看程序执行时间

    public static void main(String[] args) { long a= System.currentTimeMillis();//获取当前系统时间(毫秒) for (int ...

  6. 如何用python和苹果Turicreate学习框架来识别图像?

    大多数人听到深度学习,都会望而却步,因为会觉得很难,在这个人工智能飞速进步的时代,我也来抓一下时代的尾巴~ 两周前,我开始接触到python和Turicreate框架,经过不懈的努力,终于有所收获,特 ...

  7. 使用storm分别进行计数和词频统计

    计数 直接上代码 public class LocalStormSumTopology { public static void main(String[] agrs) { //Topology是通过 ...

  8. 【BZOJ4653】【NOI2016】区间(线段树)

    [BZOJ4653][NOI2016]区间(线段树) 题面 BZOJ 题解 \(NOI\)良心送分题?? 既然是最大长度减去最小长度 莫名想到那道反复减边求最小生成树 从而求出最小的比值 所以这题的套 ...

  9. [BZOJ1003] [ZJOI2006] 物流运输trans (最短路 & dp)

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...

  10. java 压缩文件

    package folder; import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundExcept ...