- Published on
设计模式(21)——策略 Strategy
- Authors
- Name
- Leon
二十一、Strategy(策略模式,别名 Policy 政策,对象行为型模式)
1. 意图:
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
2. 适用:
- 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
- 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式。
- 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
- 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的 Strategy 类中以代替这些条件语句。
3. 类图:
4. 应用:
系统使用不同的迭代器(正序迭代器,反序迭代器,中序迭代器)可以认为就是策略模式的一个实例。不同迭代器的使用接口和方式完全一样,当系统想要切换遍历容器的方式时,只要创建一个相应的迭代器,而使用迭代器的方式完全不用改变。
5. 中间层思考:
策略模式抽象出了一个 Strategy 类作为中间层,系统不直接访问某一个具体的算法,而是通过访问 Strategy 抽象类来调用算法,这样可以动态地在运行时切换算法。
6. C++实现:
- 编写策略抽象基类
Strategy
,含有一个纯虚函数提供算法实现的接口virtual void AlgrithmInterface() = 0;
,具体子类如ConcreteStrategyA
,ConcreteStrategyB
实现不同的算法行为。 - 编写环境类
Context
,has-a
组合一个Strategy
对象_stg
,含有一个执行函数DoAction()
,函数体内调用_stg
的算法接口AlgrithmInterface()
Strategy.h
//Strategy.h
#pragma once
class Strategy {
public:
Strategy();
virtual ~Strategy();
virtual void AlgrithmInterface() = 0;
protected:
private:
};
class ConcreteStrategyA : public Strategy {
public:
ConcreteStrategyA();
virtual ~ConcreteStrategyA();
void AlgrithmInterface();
protected:
private:
};
class ConcreteStrategyB : public Strategy {
public:
ConcreteStrategyB();
virtual ~ConcreteStrategyB();
void AlgrithmInterface();
protected:
private:
};
Strategy.cpp
//Strategy.cpp
#include "Strategy.h"
#include <iostream>
using namespace::std;
Strategy::Strategy() {}
Strategy::~Strategy() {
cout << "~Strategy......" << endl;
}
void Strategy::AlgrithmInterface(){}
ConcreteStrategyA::ConcreteStrategyA() {}
ConcreteStrategyA::~ConcreteStrategyA(){
cout << "~ConcreteStrategyA......" << endl;
}
void ConcreteStrategyA::AlgrithmInterface() {
cout << "test ConcreteStrategyA......" << endl;
}
ConcreteStrategyB::ConcreteStrategyB() {}
ConcreteStrategyB::~ConcreteStrategyB() {
cout << "~ConcreteStrategyB......" << endl;
}
void ConcreteStrategyB::AlgrithmInterface() {
cout << "test ConcreteStrategyB......" << endl;
}
Context.h
//Context.h
#pragma once
class Strategy;
/*
这个类是 Strategy 模式的关键,也是 Strategy 模式和 Template 模式的根本区别所在。
Strategy 通过“组合”(委托)方式实现算法(实现)的异构,而 Template 模式则采取的是继承方式。
这两个模式的区别也是继承和组合两种实现接口征用的方式的区别。
*/
class Context {
public:
Context(Strategy* stg);
~Context();
void DoAction();
protected:
private:
Strategy* _stg;
};
Context.cpp
//Context.cpp
#include "Context.h"
#include "Strategy.h"
#include <iostream>
using namespace::std;
Context::Context(Strategy* stg) {
_stg = stg;
}
Context::~Context() {
if (!_stg)
delete _stg;
}
void Context::DoAction() {
_stg->AlgrithmInterface();
}
main.cpp
//main.cpp
#include "Context.h"
#include "Strategy.h"
#include <iostream>
using namespace::std;
int main(int argc, char* argv[]) {
Strategy* stg = new ConcreteStrategyA();
Context* con = new Context(stg);
con->DoAction();
if (NULL != con)
delete con;
return 0;
}