设计模式 --> (3)策略模式
策略模式
策略模式是指定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也就是说这些算法所完成的功能一样,对外的接口一样,只是各自实现上存在差异。用策略模式来封装算法,效果比较好。
优点:
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)策略模式的更多相关文章
- 设计模式:策略模式(Strategy)
定 义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化, 不会影响到使用算法的客户. 示例:商场收银系统,实现正常收费.满300返100.打8折.......等不同收费 ...
- PHP设计模式之策略模式
前提: 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查 找.排序等,一种常用的方法是硬编码(Hard Cod ...
- JavaScript设计模式之策略模式(学习笔记)
在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...
- 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)
原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...
- JavaScript设计模式之策略模式
所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...
- 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查
原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...
- [design-patterns]设计模式之一策略模式
设计模式 从今天开始开启设计模式专栏,我会系统的分析和总结每一个设计模式以及应用场景.那么首先,什么是设计模式呢,作为一个软件开发人员,程序人人都会写,但是写出一款逻辑清晰,扩展性强,可维护的程序就不 ...
- 设计模式入门,策略模式,c++代码实现
// test01.cpp : Defines the entry point for the console application.////第一章,设计模式入门,策略模式#include &quo ...
- 设计模式之策略模式和状态模式(strategy pattern & state pattern)
本文来讲解一下两个结构比较相似的行为设计模式:策略模式和状态模式.两者单独的理解和学习都是比较直观简单的,但是实际使用的时候却并不好实践,算是易学难用的设计模式吧.这也是把两者放在一起介绍的原因,经过 ...
- python设计模式之策略模式
每次看到项目中存在大量的if else代码时,都会心生一丝不安全感. 特别是产品给的需求需要添加或者更改一种if条件时,生怕会因为自己的疏忽而使代码天崩地裂,哈哈,本文的目的就是来解决这种不安全感的, ...
随机推荐
- arm-linux-gcc: Command not found 问题解析 .
问题: sudo tar jxvf cross-2.95.3.tar.bz2 export PATH=$PATH:/usr/local/arm/2.95.3/bin 使用arm-linux-gcc – ...
- Oracle SQL Developer中SQL语句格式化快捷键
Oracle SQL Developer中SQL语句格式化快捷键 格式化SQL语句:Ctrl+F7
- My97 DatePicker图标触发
My97 DatePicker图标触发 1.设计源码 <%@ page language="java" import="java.util.*" page ...
- JSP中的include有哪些?有什么区别?
JSP中的include有哪些?有什么区别? 1.JSP中的include有哪些 (1)<%@include file="" %> (2)<jsp:include ...
- W: 无法下载 bzip2:/var/lib/apt/lists/partial/extras.ubuntu.com_ubuntu_dists_trusty_main_source_Sources
1 错误描述 youhaidong@youhaidong:~$ cd 下载 youhaidong@youhaidong:~/下载$ sudo apt-get update 忽略 http://cn.a ...
- Flex中对表格中某列的值进行数字格式化
1.问题背景 一般的,表格中展示的比率,对比率的处理是:保留两位小数,并向上保留 2.实现实例 <?xml version="1.0" encoding="utf- ...
- EntityFramework Core 2.0 Explicitly Compiled Query(显式编译查询)
前言 EntityFramework Core 2.0引入了显式编译查询,在查询数据时预先编译好LINQ查询便于在请求数据时能够立即响应.显式编译查询提供了高可用场景,通过使用显式编译的查询可以提高查 ...
- template.process(root, out)的用法(shiro项目中来的九)
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8" ...
- Excel2010 日文显示乱码
- Hibernate最全面试题
Hibernate常见面试题 Hibernate工作原理及为什么要用? Hibernate工作原理及为什么要用? 读取并解析配置文件 读取并解析映射信息,创建SessionFactory 打开Sess ...