策略模式(Strategy): 它定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法的变化不会影响到使用算法的客户。(原文:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.)
UML图
优点:
1、 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。 2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。 3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
缺点: 1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。 2、 在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象
源代码:
Strategy.h
#include <iostream> #include <string> #include <memory> using namespace std; class Strategy { public : virtual string substitute(string str)=0; virtual ~Strategy() { cout<<" in the destructor of Strategy" <<endl; } }; class ChineseStrategy: public Strategy { public : string substitute(string str) { int index=str.find( "520" ); string tempstr=str.replace(index,3,"我爱你" ); return tempstr; } ~ChineseStrategy() { cout<<"in the destructor of ChineseStrategy" <<endl; } }; class EnglishStrategy: public Strategy { public : string substitute(string str) { int index=str.find( "520" ); string tempstr=str.replace(index,3,"i love ou" ); return tempstr; } ~EnglishStrategy() { cout<<" in the destructor of ChineseStrategy" <<endl; } };
class Translator { private : auto_ptr<Strategy> strategy;
public : ~Translator() { cout<<" in the destructor of Translator" <<endl; } void set_strategy(auto_ptr<Strategy> strategy) { this ->strategy=strategy; } string translate(string str) { if (0==strategy.get()) return "" ; return strategy->substitute(str); } };
Strategy.cpp
#include "Strategy.h" int main( int argc, char *argv) { string str("321520" ); Translator *translator=new Translator; cout<<"No Strategy" <<endl; translator->translate(str); cout<<"---------------" <<endl; auto_ptr<Strategy> s1(new ChineseStrategy); translator->set_strategy(s1); cout<<"Chinese Strategy" <<endl; cout<<translator->translate(str)<<endl; cout<<"---------------" <<endl; auto_ptr<Strategy> s2(new EnglishStrategy); translator->set_strategy(s2); cout<<"English Strategy" <<endl; cout<<translator->translate(str)<<endl; cout<<"----------------" <<endl; delete translator; return 0; }