The Programming world of Alex

设计模式之Strategy模式

Strategy模式是设计模式中非常常用的一种设计模式,甚至在你没有学习过设计模式之前就已经使用过这种模式。先看个简单的例子吧:
比如说你要写个List的容器,需要有一个Sort方法。但是对于容器中不同类型的对象Sort方法可能会不一样,比如说Point类型可能根据point到原点的距离或者point的xy之和来比较大小。
一种很自然的想法就是:
1void sort()
2{
3  //按到原点距离排序
4  if()
5  {}
6  //按XY之和大小排序
7  else if()
8  {}
9}
但是说不定哪天Boss说:“我要按X的大小排序,你把Sort重写一下”,这难道不是让人抓狂?

好在我们有Stratregy模式能搞定这类变化问题(设计模式的根本目的就是在于抑制变化对程序的影响)

动机:
软件构建中,某些对象使用的算法可能多种多样,我们需要的是将算法和对象本身解耦,在运行时根据需要透明地更改对象的算法。

意图:
定义一系列的算法,把他们一个个封装起来,并且使他们可以相互替换。该模式使得算法可以独立于它的客户而变化。(GoF23)

设计思路:
我们的目的是让Context能在各种Algorithm之间切换,如下图:


上图就是设计Sort时所用的最容易想到的方法,Context和三种Algorithm之间是紧耦合关系,对于需求的变化无能为力。

下图仍然运用的是OO中的“依赖倒置原则”,使用接口将算法和对象解耦,抽象出描述算法功能要求的IStrategy接口。这样Context和IStrategy成为相对稳定的松耦合关系,运行时多态来控制到底运用何种算法来解决实际问题,而避免了if...else...的静态控制。

总结:
1.“依赖倒置原则”,抽象出接口,使得Context“间接”依赖算法,两者由紧耦合变为送耦合。
2.对于不同的算法,分别封装成为具体类,实现接口要求的功能(多态应用)。
3.Strategy模式简单说就是实现了算法的“静态切换”到“动态切换”的转变(不光是算法,其他也都可以)。大多数情况下的if...else...和switch...case...(静态切换)都能用Strategy模式(动态切换)来替换,这也是Strategy模式广泛使用的原因。

关于释放内存:
非常感谢有朋友指出我代码中存在的问题
主要的问题是如何对Context中的释放IS指针指向的内存,具体还是看代码中的Method函数和析构函数,如果还有问题欢迎继续指正 :-)
(指针初始化赋NULL,delete后仍然赋NULL,养成好习惯:-))

自己做的示例代码,仅供参考
 1//////////////////////////////////////////////////////////////////////////
 2//StrategyTest For Strategy Pattern
 3//
 4//////////////////////////////////////////////////////////////////////////
 5
 6#include "stdafx.h"
 7#include <iostream>
 8using namespace std;
 9
10//策略类,不同算法的抽象接口
11class IStrategy
12{
13public:
14    virtual void process()=0;
15}
;
16
17//算法的具体实现
18class StrategyA:public IStrategy
19{
20public:
21    void process()
22    {
23        cout<<"StrategyA"<<endl;
24    }

25}
;
26
27class StrategyB:public IStrategy
28{
29public:
30    void process()
31    {
32        cout<<"StrategyB"<<endl;
33    }

34}
;
35
36class StrategyC:public IStrategy
37{
38public:
39    void process()
40    {
41        cout<<"StrategyC"<<endl;
42    }

43}
;
44
45//需要切换算法的上下文类
46class Context
47{
48private:
49    IStrategy* IS;
50public:
51    //构造函数
52    Context()
53    {
54        IS = NULL;
55    }

56    //使用不同类型的算法
57    void method(IStrategy *IS)
58    {
59        //首先检查指针是否为空,不为空则释放指针
60        if ((this->IS) != NULL) 
61        
62            delete (this->IS); 
63            this->IS = NULL;
64        }

65        //对指针赋值
66        this->IS = IS;
67        //////////////////////////////////////////////////////////////////////////
68        //一些操作
69        //////////////////////////////////////////////////////////////////////////
70
71        //调用算法
72        this->IS->process();
73    }

74    //析构函数,释放指针
75    ~Context()
76    {
77        if (this->IS != NULL) { delete this->IS; }
78    }

79}
;
80
81int _tmain(int argc, _TCHAR* argv[])
82{
83    Context* context = new Context();
84
85    //Context使用算法A
86    cout<<"Context use the AlgorithmA:              "<<endl;
87    context->method(new StrategyA());
88
89    //Context使用算法B
90    cout<<"Context use the AlgorithmB:              "<<endl;
91    context->method(new StrategyB());
92
93    //Context使用算法C
94    cout<<"Context use the AlgorithmC:              "<<endl;
95    context->method(new StrategyC());
96
97    return 0;
98}

posted on 2009-04-06 15:21 Alex@VCC 阅读(3134) 评论(7)  编辑 收藏 引用 所属分类: 设计模式

评论

# re: 设计模式之Strategy模式 2009-04-06 18:51 lfly

第一次看Strategy模式的解释,谢谢博主的说明。感觉就是使用了虚函数的运行时动态绑定的特性吧?  回复  更多评论   

# re: 设计模式之Strategy模式[未登录] 2009-04-06 18:52 Alex@VCC

@lfly
恩,基本就是这样子的:)  回复  更多评论   

# re: 设计模式之Strategy模式 2009-04-07 09:46 星绽紫辉

nice.  回复  更多评论   

# re: 设计模式之Strategy模式[未登录] 2009-04-07 12:03 jcily

感谢分享,比看书理解的快。  回复  更多评论   

# re: 设计模式之Strategy模式 2009-04-09 23:10 Kim

我发现博主很喜欢用NEW来构建对象哦。。但之后却没用DELETE来释放内存。。这不是JAVA。。C++没垃圾回收机制。。。  回复  更多评论   

# re: 设计模式之Strategy模式 2009-04-10 13:15 Alex@VCC

@Kim
非常感谢提醒,释放内存十分重要,我确实是忽略了这个问题
最近太忙,有时间会把Delete的使用集成到这些模式里去
  回复  更多评论   

# re: 设计模式之Strategy模式 2010-11-16 10:56 rain

@Alex@VCC
LZ 的UML图好像画错了哦!  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

导航

统计

常用链接

留言簿(5)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜