行为型模式:Strategy——策略模式
2011-05-17 12:26
295 查看
一、意图
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换,本模式使得算法可独立于使用它的客户而变化——四人团二、基本思想
定义算法家族,分别封装起来,让它们之间可以互相替换,让算法的变化,不会影响到使用算法的用户。三、优缺点分析
GOOD:(1)策略模式是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同。
所以使用策略模式,就可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
(2)策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能
(3)简化了单元测试(因为每个算法都有自己的类,可以通过自己的接口单独测试)
BUG:客户端要做出判断使用哪个具体算法(可通过在context中与工厂模式的结合来消除这个问题,虽然当新增加需求时,还是要改context中的代码,但是任何需求的变更本身就是需要成本的)
四、适用情况
策略模式和简单工厂基本相同,但简单工厂模式只能解决对象创建问题,对于类中的成员以方法为主,而且算法经常变动的类,应使用策略模式。在实践中,策略模式实际上可以封装几乎任何类型的规则,只要在分析过程中听到需要不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
五、标准UML图例及源码
(1)标准UML图列
(2)标准源码
/************************************************************************
* FileName: Strategy.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 抽象算法类:定义所有支持的算法的公共接口
* Time: 2010/5/24
************************************************************************/
#ifndef STRATEGY_H
#define STRATEGY_H
class Strategy
{
public:
virtual ~Strategy(){}
// 算法方法
virtual void AlgorithmInterface() = 0;
};
#endif
/************************************************************************
* FileName: Context.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 上下文类,用一个ConcreateStrategy来配置,维护一个对Strategy对象的引用
* Time: 2010/5/24
************************************************************************/
#ifndef CONTEXT_H
#define CONTEXT_H
#include "Strategy.h"
#include <iostream>
class Context
{
public:
Context(Strategy *pStrategy);// 构造时,传入具体的策略对象
~Context();
void ContextInterface();// 根据具体的策略对象,调用其算法的方法
private:
Strategy* m_pStrategy;
};
#endif // CONTEXT_H
1:/************************************************************************
* FileName: ConcreateStrategyA.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 具体算法类A:封装了具体的算法或行为,继承于Strategy
* Time: 2010/5/24
************************************************************************/
#ifndef CONCREATESTRATEGYA_H
#define CONCREATESTRATEGYA_H
#include "Strategy.h"
#include <iostream>
class ConcreateStrategyA
: public Strategy
{
public:
virtual ~ConcreateStrategyA(){}
// 算法A实现方法
virtual void AlgorithmInterface();
};
#endif // CONCREATESTRATEGYA_H
/************************************************************************
* FileName: ConcreateStrategyB.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 具体算法类B:封装了具体的算法或行为,继承于Strategy
* Time: 2010/5/24
************************************************************************/
#ifndef CONCREATESTRATEGYB_H
#define CONCREATESTRATEGYB_H
#include "Strategy.h"
#include <iostream>
class ConcreateStrategyB
: public Strategy
{
public:
virtual ~ConcreateStrategyB(){}
// 算法B实现方法
virtual void AlgorithmInterface();
};
#endif // CONCREATESTRATEGYB_H
/************************************************************************
* FileName: ConcreateStrategyC.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 具体算法C:封装了具体的算法或行为,继承于Strategy
* Time: 2010/5/24
************************************************************************/
#ifndef CONCREATESTRATEGYC_H
#define CONCREATESTRATEGYC_H
#include "Strategy.h"
#include <iostream>
class ConcreateStrategyC
: public Strategy
{
public:
virtual ~ConcreateStrategyC(){}
// 算法C实现方法
virtual void AlgorithmInterface();
};
#endif // CONCREATESTRATEGYC_H
/************************************************************************
* FileName: Context.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 上下文类的具体实现
* Time: 2010/5/24
************************************************************************/
#include "Context.h"
// 构造时,传入具体的策略对象
Context::Context(Strategy *pStrategy)
: m_pStrategy(pStrategy)
{
}
Context::~Context()
{
delete m_pStrategy;
m_pStrategy = NULL;
}
// 根据具体的策略对象,调用其算法的方法
void Context::ContextInterface()
{
if (NULL != m_pStrategy)
{
m_pStrategy->AlgorithmInterface();
}
}
/************************************************************************
* FileName: ConcreateStrategyA.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : ConcreateStrategyA类的具体实现
* Time: 2010/5/24
************************************************************************/
#include "ConcreateStrategyA.h"
// 算法A实现方法
void ConcreateStrategyA::AlgorithmInterface()
{
std::cout << "AlgorithmInterface Implemented by ConcreateStrategyA\n";
}
/************************************************************************
* FileName: ConcreateStrategyC.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : ConcreateStrategyC类的具体实现
* Time: 2010/5/24
************************************************************************/
#include "ConcreateStrategyC.h"
// 算法C实现方法
void ConcreateStrategyC::AlgorithmInterface()
{
std::cout << "AlgorithmInterface Implemented by ConcreateStrategyC\n";
}
/************************************************************************
* FileName: ConcreateStrategyB.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : ConcreateStrategyB类的具体实现
* Time: 2010/5/24
************************************************************************/
#include "ConcreateStrategyB.h"
// 算法B实现方法
void ConcreateStrategyB::AlgorithmInterface()
{
std::cout << "AlgorithmInterface Implemented by ConcreateStrategyB\n";
}
/************************************************************************
* FileName: Main.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : Strategy模式的测试代码
* Time: 2010/5/24
************************************************************************/
#include "Context.h"
#include "ConcreateStrategyA.h"
#include "ConcreateStrategyB.h"
#include "ConcreateStrategyC.h"
int main()
{
Strategy* pStrategy;
/**
* 由于实例化不同的策略,所以最终在调用实际的算法时,所获得结果就不尽相同
*/
pStrategy = new ConcreateStrategyA();
Context*pContext1= new Context(pStrategy);
pContext1->ContextInterface();
pStrategy = new ConcreateStrategyB();
Context*pContext2= new Context(pStrategy);
pContext2->ContextInterface();
pStrategy = new ConcreateStrategyC();
Context*pContext3= new Context(pStrategy);
pContext3->ContextInterface();
delete pContext1;
delete pContext2;
delete pContext3;
return 0;
}
六、实例UML图及源码
(1)纯策略模式
/************************************************************************
* FileName: CashSuperStratrgy.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 抽象收费算法类:定义所有支持的收费算法的公共接口
* Time: 2010/5/24
************************************************************************/
#ifndef CASHSUPERSTRATEGY_H
#define CASHSUPERSTRATEGY_H
class CashSuperStrategy
{
public:
CashSuperStrategy(){}
virtual ~CashSuperStrategy(){}
// 收费算法
virtual double AcceptCash(double dMoney) = 0;
protected:
private:
};
#endif // CASHSUPERSTRATEGY_H
/************************************************************************
* FileName: CashContext.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 上下文类,用一个CashConcreateStrategy来配置,维护一个对CashSuperStratrgy对象的引用
* Time: 2010/5/24
************************************************************************/
#ifndef CASHCONTEXT_H
#define CASHCONTEXT_H
#include "CashSuperStrategy.h"
#include <iostream>
class CashContext
{
public:
CashContext(CashSuperStrategy *pCashSuperStrategy);//构造时,传入具体的收费策略对象
~CashContext();
double GetResult(double dMoney);// 根据具体的收费策略对象,获得具体的计算结果
protected:
private:
CashSuperStrategy* m_pCashSuperStrategy;
};
#endif // CASHCONTEXT_H
/************************************************************************
* FileName: CashContext.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : CashContext的具体实现
* Time: 2010/5/24
************************************************************************/
#include "CashContext.h"
CashContext::CashContext(CashSuperStrategy * pCashSuperStrategy)
{
//ctor
this->m_pCashSuperStrategy = pCashSuperStrategy;
}
CashContext::~CashContext()
{
//dtor
delete m_pCashSuperStrategy;
m_pCashSuperStrategy = NULL;
}
double CashContext::GetResult(double dMoney)
{
return m_pCashSuperStrategy->AcceptCash(dMoney);
}
/************************************************************************
* FileName: CashNormalStrategy.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 具体的正常收费算法类CashNormalStrategy:封装了具体的正常收费算法,继承于Strategy
* Time: 2010/5/24
************************************************************************/
#ifndef CASHNORMALSTRATEGY_H
#define CASHNORMALSTRATEGY_H
#include "CashSuperStrategy.h"
class CashNormalStrategy : public CashSuperStrategy
{
public:
CashNormalStrategy();
virtual ~CashNormalStrategy();
// 具体的收费算法
virtual double AcceptCash(double dMoney);
protected:
private:
};
#endif // CASHNORMALSTRATEGY_H
/************************************************************************
* FileName: CashNormalStrategy.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : CashNormalStrategy的具体实现
* Time: 2010/5/24
************************************************************************/
#include "CashNormalStrategy.h"
CashNormalStrategy::CashNormalStrategy()
{
//ctor
}
CashNormalStrategy::~CashNormalStrategy()
{
//dtor
}
double CashNormalStrategy::AcceptCash(double dMoney)
{
return dMoney;
}
/************************************************************************
* FileName: CashRebateStrategy.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 具体的打则收费算法类CashNormalStrategy:封装了具体的打折收费算法,继承于Strategy
* Time: 2010/5/24
************************************************************************/
#ifndef CASHREBATESTRATEGY_H
#define CASHREBATESTRATEGY_H
#include "CashSuperStrategy.h"
class CashRebateStrategy : public CashSuperStrategy
{
public:
CashRebateStrategy(double dMoneyRebate);
virtual ~CashRebateStrategy();
// 具体的收费算法
virtual double AcceptCash(double dMoney);
protected:
private:
double m_dMoneyRebate;
};
#endif // CASHREBATESTRATEGY_H
/************************************************************************
* FileName: CashRebateStrategy.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : CashRebateStrategy的具体实现
* Time: 2010/5/24
************************************************************************/
#include "CashRebateStrategy.h"
CashRebateStrategy::CashRebateStrategy(double dMoneyRebate)
{
//ctor
this->m_dMoneyRebate = dMoneyRebate;
}
CashRebateStrategy::~CashRebateStrategy()
{
//dtor
}
double CashRebateStrategy::AcceptCash(double dMoney)
{
return dMoney * m_dMoneyRebate;
}
/************************************************************************
* FileName: CashReturnStrategy.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 具体的返现收费算法类CashReturnStrategy:封装了具体的返现收费算法,继承于Strategy
* Time: 2010/5/24
************************************************************************/
#ifndef CASHRETURNSTRATEGY_H
#define CASHRETURNSTRATEGY_H
#include "CashSuperStrategy.h"
class CashReturnStrategy : public CashSuperStrategy
{
public:
CashReturnStrategy(double dMoneyCondition, double dMoneyReturn);
virtual ~CashReturnStrategy();
// 具体的收费算法
virtual double AcceptCash(double dMoney);
protected:
private:
double m_dMoneyCondition;
double m_dMoneyReturn;
};
#endif // CASHRETURNSTRATEGY_H
/************************************************************************
* FileName: CashReturnStrategy.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : CashReturnStrategy
* Time: 2010/5/24
************************************************************************/
#include "CashReturnStrategy.h"
CashReturnStrategy::CashReturnStrategy(double dMoneyCondition, double dMoneyReturn)
{
//ctor
this->m_dMoneyCondition = dMoneyCondition;
this->m_dMoneyReturn = dMoneyReturn;
}
CashReturnStrategy::~CashReturnStrategy()
{
//dtor
}
double CashReturnStrategy::AcceptCash(double dMoney)
{
double result = dMoney;
if (dMoney >= m_dMoneyCondition)
{
result = dMoney - (int)(dMoney / m_dMoneyCondition) * m_dMoneyReturn;
}
return result;
}
(2)策略与工厂结合
GOOD:客户端只需访问Context类,而不用知道其它任何类信息,实现了低耦合。在上例基础上,增加一个结合了工厂模式的类
/************************************************************************
* FileName: CashContextWithFactory.h
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 结合了工厂类的上下文类定义
* Time: 2010/5/24
************************************************************************/
#ifndef CASHCONTEXTWITHFACTORY_H
#define CASHCONTEXTWITHFACTORY_H
#include "CashSuperStrategy.h"
#include "CashNormalStrategy.h"
#include "CashRebateStrategy.h"
#include "CashReturnStrategy.h"
#include <iostream>
class CashContextWithFactory
{
public:
CashContextWithFactory(int type);//构造时,传入具体的收费策略类型,构造函数中自行根据类型创建对应收费类对象
virtual ~CashContextWithFactory();
double GetResult(double dMoney);// 根据具体的收费策略对象,获得具体的计算结果
protected:
private:
CashSuperStrategy* m_pCashSuperStrategy;
};
#endif // CASHCONTEXTWITHFACTORY_H
/************************************************************************
* FileName: CashContextWithFactory.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : CashContextWithFactory的具体实现
* Time: 2010/5/24
************************************************************************/
#include "CashContextWithFactory.h"
//构造时,传入具体的收费策略类型,构造函数中自行根据类型创建对应收费类对象
CashContextWithFactory::CashContextWithFactory(int type)
{
//ctor
switch (type)
{
case 0:
m_pCashSuperStrategy = new CashNormalStrategy();
break;
case 1:
m_pCashSuperStrategy = new CashRebateStrategy(0.8);
break;
case 2:
m_pCashSuperStrategy = new CashReturnStrategy(300, 100);
break;
default:
break;
}
}
CashContextWithFactory::~CashContextWithFactory()
{
//dtor
delete m_pCashSuperStrategy;
m_pCashSuperStrategy = NULL;
}
double CashContextWithFactory::GetResult(double dMoney)
{
return m_pCashSuperStrategy->AcceptCash(dMoney);
}
(3)测试代码
/************************************************************************
* FileName: main.cpp
* Author: steven oyj (steven.oyj@gmail.com)
* Description : 策略模型及其与工厂模式结合的测试主函数
* Time: 2010/5/24
************************************************************************/
#include <iostream>
#include "CashContext.h"
#include "CashNormalStrategy.h"
#include "CashRebateStrategy.h"
#include "CashReturnStrategy.h"
#include "CashContextWithFactory.h"
using namespace std;
void PureStratrgyTest();
void StrategyWithFactoryTest();
int main()
{
PureStratrgyTest();
StrategyWithFactoryTest();
return 0;
}
/**
* 由于实例化不同的收费策略类对象,所以最终在调用实际的收费算法时,所获得结果就不尽相同
*/
void PureStratrgyTest()
{
CashSuperStrategy* pStrategy;
pStrategy = new CashNormalStrategy();
CashContext*pContext1= new CashContext(pStrategy);
cout << pContext1->GetResult(800) << endl;
pStrategy = new CashRebateStrategy(0.8);
CashContext*pContext2= new CashContext(pStrategy);
cout << pContext2->GetResult(800) << endl;
pStrategy = new CashReturnStrategy(300, 100);
CashContext*pContext3= new CashContext(pStrategy);
cout << pContext3->GetResult(800) << endl;
delete pContext1;
delete pContext2;
delete pContext3;
}
/**
* 结合工厂模式,传入不同收费策略的指令参数,
* 由上下文类中的工厂自行实例化不同的收费策略类对象
* 所以最终在调用实际的收费算法时,所获得结果就不尽相同
*/
void StrategyWithFactoryTest()
{
CashContextWithFactory* pContext1 = new CashContextWithFactory(0);
cout << pContext1->GetResult(800) << endl;
CashContextWithFactory* pContext2 = new CashContextWithFactory(1);
cout << pContext2->GetResult(800) << endl;
CashContextWithFactory* pContext3 = new CashContextWithFactory(2);
cout << pContext3->GetResult(800) << endl;
delete pContext1;
delete pContext2;
delete pContext3;
}
相关文章推荐
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- 设计模式 (一)——策略模式(Strategy,行为型)
- 设计模式(4)-行为型-策略模式(Strategy)
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- 设计模式22:Strategy 策略模式(行为型模式)
- 二十三、 Strategy 策略(行为型模式)
- 设计模式(4)-行为型-策略模式(Strategy)
- 设计模式(九):策略模式Strategy(行为型模式)
- 行为型模式-----策略模式(Strategy)
- 设计模式--行为型-Strategy(策略)
- 设计模式(Design Pattern) - 行为型模式(Behavioral Pattern) - 策略模式(Strategy) - Java实现
- 【行为型模式】策略模式(Strategy)之23种java设计模式
- 3.9 Strategy(策略) -- 对象行为型模式
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
- 设计模式(4)-行为型-策略模式(Strategy)
- 设计模式(21)-行为型-策略模式(Strategy)
- Strategy模式(策略模式 行为型)
- Strategy 策略(行为型模式)--学习笔记
- 策略模式Strategy(对象行为型)