1、策略模式

在策略模式中,我们可以定义一些独立的类来封装不同的算法,每一个类封装一种具体的算法,在这里,每一个封装算法的类我们都可以称之为一种策略(Strategy),为了保证这些策略在使用时具有一致性,一般会提供一个抽象的策略类来做规则的定义,而每种算法则对应于一个具体策略类。

策略模式的主要目的是将算法的定义与使用分开,也就是将算法的行为和环境分开,将算法的定义放在专门的策略类中,每一个策略类封装了一种实现算法,使用算法的环境类针对抽象策略类进行编程,符合“针对抽象进行编程原则”。在出现新的算法时,只需要增加一个新的实现了抽象策略类的具体策略类即可。策略模式定义如下:

策略模式(Strategy Pattern):定义一系列算法类,将每一个算法封装起来,并让它们可以相互替换,策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。策略模式是一种对象行为型模式。

策略模式结构并不复杂,但我们需要理解其中环境类Context。

在策略模式结构图中包含如下几个角色:

Context(环境类):环境类是使用算法的角色,在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略,实际上环境类将调用策略类中实现算法的方法。环境类针对抽象策略进行编程,无需知道具体是哪一种策略,只要该策略类中实现了具体的算法方法就可以。在同一时刻,环境类只能使用一种策略,而不能使用多种。

Strategy(抽象策略类):它为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类,也可以是接口。环境类通过抽象策略类中声明的方法在运行时调用具体策略类中实现的算法。

ConcreteStrategy(具体策略类):它实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理。

策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列具体策略类里面,作为抽象策略类的子类。在策略模式中,对环境类和抽象策略类的理解非常重要,环境类是需要使用算法的类。

2、游戏武器系统的设计与实现

现需要开发一款射击类游戏,玩家可以选择斧头、手枪、AK47冲锋枪三种武器,每种武器都有不同的杀伤力等级,如斧头杀伤力6级,手枪杀伤力8级,AK47杀伤力10级。要求系统具有扩展性,如果有其他的武器,可以直接进行扩展,请使用策略模式进行设计。

可以设计一个抽象武器类,具体武器如斧头、手枪、AK47继承于抽象武器类。

武器类的实现代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef _WEAPON_H_
#define _WEAPON_H_
#include <iostream>
#include <string>
using namespace std;
//抽象武器类(抽象策略)
class Weapon
{
public :
     //虚方法,使用武器打斗
     virtual void Fight(string Player) = 0 ;
};
//手枪(具体策略)
class Gun : public Weapon
{
public :
     void Fight(string Player, int nKillAbility)
     {
         cout << "游戏玩家:" << Player << "   战斗力:8级" << endl;
     }
};
//Ak47冲锋枪(具体策略)
class Ak47 : public Weapon
{
public :
     void Fight(string Player)
     {
         cout << "游戏玩家:" << Player << "   战斗力:10级" <<  endl;
     }
};
//斧头(具体策略)
class Axe : public Weapon
{
public :
     void Fight(string Player)
     {
         cout << "游戏玩家:" << Player << "   战斗力:6级" <<  endl;
     }
};
#endif</string></iostream>

Weapon是抽象策略类,具体武器Gun、Ak47、Axe是具体的策略类。每个具体策略实现抽象策略中打斗方法。

现在需要设计一个游戏玩家类,也就是环境类,游戏玩家来使用具体的某种武器。游戏玩家实现代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#ifndef _PLAYER_H_
#define _PLAYER_H_
#include <iostream>
#include <string>
#include "Weapon.h"
using namespace std;
//游戏玩家(环境类)
class Player
{
private :
     //玩家名称
     string m_strPlayer;
     //玩家使用的武器
     Weapon * m_pWeapon;
public :
     //设置玩家名称
     void SetPlayer(string strPlayer)
     {
         m_strPlayer = strPlayer;
     }
     //设置玩家使用的武器
     void SetWeapon(Weapon * pWeapon)
     {
         m_pWeapon = pWeapon;
     }
     //玩家使用武器打斗
     void Fight()
     {
         m_pWeapon->Fight(m_strPlayer);
     }
};
#endif</string></iostream>

游戏玩家Player维持一个武器类对象的引用。当玩家需要使用某种武器的时候,只需要把武器通过SetWeapon设置给玩家,玩家就可以通过使用这种武器进行打斗操作,实际上调用的仍是武器类的打斗方法。测试代码实现如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include "Player.h"
#include "Weapon.h"
using namespace std;
int main()
{
     //创建Ak47武器对象
     Weapon * pAk47 = new Ak47();
     //创建玩家对象
     Player * pPlayer = new Player();
     pPlayer->SetPlayer( "挑战者" );
     pPlayer->SetWeapon(pAk47);
     //打斗
     pPlayer->Fight();
      
         //销毁操作
     delete pPlayer;
     pPlayer = NULL;
     delete pAk47;
     pAk47 = NULL;
     return 0 ;
}</iostream>

编译并运行,结果如下:

因为游戏玩家(环境类)针对抽象武器策略进行编程。如果需要更换武器策略,无需修改代码,只需要把具体武器策略设置给游戏玩家就可以了,可以随时切换武器。环境类不需要知道具体使用哪种策略,符合"针对抽象编程原则"。如果需要添加新的武器,只需要增加一个新的武器类,作为抽象武器类的子类,实现抽象类中的打斗方法。无需修改之前的代码,符合"开放封闭原则"。

3、策略模式总结

策略模式用于算法的自由切换和扩展,它是应用较为广泛的设计模式之一。策略模式对应于解决某一问题的一个算法族,允许用户从该算法族中任选一个算法来解决某一问题,同时可以方便地更换算法或者增加新的算法。只要涉及到算法的封装、复用和切换都可以考虑使用策略模式。如果需要添加新的策略,只需要增加一个新的策略类,作为抽象策略类的子类,实现抽象类中的方法,无需修改之前的代码,符合"开放封闭原则"。环境类针对抽象策略进行编程,如果需要更换,只需要把具体策略设置给环境类就可以了,可以随时切策略。环境类不需要知道具体使用哪种策略,符合"针对抽象编程原则。由于引进了环境类,客户端不需要直接操作具体策略,而是由环境类对策略进行操作处理。环境类起承上启下的作用,屏蔽高层模块对策略算法的直接访问,封装可能存在的变化。环境类和策略类是一种组合关系,通过组合实现对策略类代码的复用。

1.主要优点

策略模式的主要优点如下:

(1) 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。

(2) 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族,恰当使用继承可以把公共的代码移到抽象策略类中,从而避免重复的代码。

(3) 使用策略模式可以避免多重条件选择语句。多重条件选择语句不易维护,它把采取哪一种算法或行为的逻辑与算法或行为本身的实现逻辑混合在一起,将它们全部硬编码在一个庞大的多重条件选择语句中,比直接继承环境类的办法还要原始和落后。使用策略模式,if逻辑被封装到各个策略中。

(4) 策略模式提供了一种算法的复用机制,由于将算法单独提取出来封装在策略类中,因此不同的环境类可以方便地复用这些策略类。

2.主要缺点

策略模式的主要缺点如下:

(1) 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。违背"迪米特法则,也就是和直接朋友通信原则",可以通过简单工厂模式来解决这个问题。

(2) 策略模式将造成系统产生很多具体策略类,任何细小的变化都将导致系统要增加一个新的具体策略类。

(3) 无法同时在客户端使用多个策略类,也就是说,在使用策略模式时,客户端每次只能使用一个策略类,不支持使用一个策略类完成部分功能后再使用另一个策略类来完成剩余功能的情况。

3.策略模式具体应用

(1)电影院打折算法,成年人全票、VIP6折、儿童票与学生票0.5折优惠。

(2)数据导出:可以导出到数据库、也可以导出到Xml,或者文本文件中。比如:系统异常信息Log,可以记录到数据库也可以记录到文件中。再如:网页上的信息可以转为Word格式保存,也可以转为PDF格式保存。

(3)网络购物,可以选择货到付款、也可以选择U盾支付、还可以选择支付宝支付等支付方式。

(4)对于加密软件的开发,可以选择不同类型的加密算法,肯定不会只有一种加密算法。同样遍历二叉树,存在先序遍历。中序遍历、后序遍历、层序遍历等四种遍历算法,根据需要选择具体的某种遍历算法。还有数据结构中的各种排序算法,根据具体情况选择某个排序算法。

(5)QQ空间背景风格,可以根据需要选择某种喜欢的风格,用来装扮空间。

(6)UI容器管理器,用于管理各种类型控件布局方式。存在多种不同的布局方式,根据美观程度,选择某种布局方式。

(7)生活中的策略: 条条道路通罗马,36行行行出状元,描述的就是各种策略;人生面临着许多选择,路怎么走,该往哪里走。选择正确,可能一辈子飞黄腾达,选择错误,也许一辈就默默无闻了,这是一种人生选择策略。

设计模式(二)--策略模式相关推荐

  1. Java设计模式之策略模式与状态模式

    一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. 好了,定义看看就完了,我知道你很烦看定义. 二.策 ...

  2. 研磨设计模式之 策略模式--转

    http://www.uml.org.cn/sjms/201009092.asp 研磨设计模式之 策略模式   2010-09-09 作者:云飞龙行 来源:云飞龙行的blog   先感谢众多朋友的支持 ...

  3. python策略模式包含角色_详解Python设计模式之策略模式

    虽然设计模式与语言无关,但这并不意味着每一个模式都能在每一门语言中使用.<设计模式:可复用面向对象软件的基础>一书中有 23 个模式,其中有 16 个在动态语言中"不见了,或者简 ...

  4. 换个姿势学设计模式:策略模式

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源:公众号「闻人的技术博客」 前言 前段时间,接到一个 ...

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

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

  6. C++设计模式之策略模式(Strategy)

    Strategy策略模式 作用:定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. UML图: 代码实现 #include <iostream& ...

  7. 一篇博客读懂设计模式之-----策略模式

    设计模式之策略模式 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的对象 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换. 主要解决:在有多种算法相似的情况下 ...

  8. 面向对象设计模式之策略模式

    面向对象设计模式之策略模式 1.策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户 2.抽象鸭子类,鸭子飞行行为在此处类似于算法族 1 package ...

  9. java策略模式详解_Java经典设计模式之策略模式原理与用法详解

    本文实例讲述了Java经典设计模式之策略模式.分享给大家供大家参考,具体如下: 策略模式指:策略模式指将程序中可变部分抽象分离成一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式 ...

  10. 策略设计模式_设计模式之策略模式总结

    再上一篇文章<设计模式之策略模式>中,我们通过模拟鸭子项目,了解了什么是策略模式,怎么使用策略模式.本文将通过鸭子项目的学习,对策略模式进行总结. 策略模式: 分别封装行为接口,实现算法族 ...

最新文章

  1. Android调用浏览器打开网址遇到的问题
  2. pre-network android预加载网络框架
  3. Linux中变量#,#,@,0,0,1,2,2,*,$$,$?的含义
  4. Java 基本功之(三)Java 核心技术
  5. python pandas爬取网页成绩表格,计算各个类别学分
  6. 设计模式09----门面设计模式
  7. 总结之前有道笔记的内容--对于postdelay方法的讲解
  8. 华为Mate8 NFC 时好时坏,怎么解决呢?
  9. 看了这份《算法中文手册》笔记,就再也不怕字节了~
  10. DEFERRED_SEGMENT_CREATION
  11. 利用deepface网络进行表情分类
  12. bat脚本 rar压缩文件 rar压缩文件带一层路径 带路径压缩
  13. UML概要基础知识(待完善)
  14. Windows 使用 CMD 命令行下载文件
  15. 局域网内window10和Windows7共享只有USB接口打印机的方法——以sharp2048D为例子
  16. C#使用libVLC制作视频播放器时自定义鼠标事件的捕获或者忽略
  17. 软件设计师必考精华 - 面相对象
  18. mysql里一个中文汉字占多少字节数?
  19. vue展示日历 考勤展示_vue实现日历组件
  20. Efficient Image Dehazing with Boundary Constraint and Contextual Regularization

热门文章

  1. 如何写好一篇优质的网站内容
  2. 待过猫厂、狗厂、鹅厂、猪厂的10年测试码农告诉你-测试计划与测试方案的区别?
  3. RT-Thread柿饼常用应用代码汇总
  4. vue的v-for循环中图片加载路径问题
  5. 【电影推荐】风吹麦浪
  6. 《使用IEC61499为控制系统建模》-第一章 概述
  7. C++实验八——类的继承(2)
  8. js框架jquery实现的幸运大转盘抽奖程序代码,兼容多种浏览器(Internet Explorer 6.0+ 、Firefox 2.0 、Safari 3 、Opera 9 、Chrome)
  9. “小镇青年”、“互联网老兵”、“币圈韭菜” 玉红的众多标签为哪般?
  10. 全国计算机三级答案,全国计算机三级数据库技术笔试试题(附正确答案)