Strategy模式
Strategy模式
Strategy模式要解决的问题和Template模式类似。都是为了把算法的声明和算法的实现解耦。Template模式是通过继承来实现的,而Strategy模式是通过组合来实现的。
Strategy模式将算法封装到一个类(Context)里面。通过组合的方式将算法在组合的对象中实现。之后通过托付将抽象接口托付给组合对象来实现。其类结构图例如以下:
实现
//Strategy.h
//Strategy.h
class Strategy
{
public:
virtual void PrimitiveOperation() = 0;
virtual ~Strategy();
protected:
Strategy();
};
class ConcreteStrategy1 :public Strategy
{
public:
ConcreteStrategy1();
~ConcreteStrategy1();
void PrimitiveOperation();
};
class ConcreteStrategy2 :public Strategy
{
public:
ConcreteStrategy2();
~ConcreteStrategy2();
void PrimitiveOperation();
};
//Strategy.cpp
//Strategy.cpp
#include"Strategy.h"
#include<iostream>
using namespace::std;
Strategy::Strategy()
{}
Strategy::~Strategy()
{}
ConcreteStrategy1::ConcreteStrategy1()
{}
ConcreteStrategy1::~ConcreteStrategy1()
{}
void ConcreteStrategy1::PrimitiveOperation()
{
cout << "ConcreteStrategy1 PrimitiveOperation()" << endl;
}
ConcreteStrategy2::ConcreteStrategy2()
{}
ConcreteStrategy2::~ConcreteStrategy2()
{}
void ConcreteStrategy2::PrimitiveOperation()
{
cout << "ConcreteStrategy2 PrimitiveOperation()" << endl;
}
//Context.h
//Context.h
#ifndef _CONTEXT_H_
#define _CONTEXT_H_
class Strategy;
class Context
{
public:
Context(Strategy*);
~Context();
void DoAction();
private:
Strategy* _strategy;
};
#endif
//Context.cpp
//Context.cpp
#include"Context.h"
#include"Strategy.h"
Context::Context(Strategy* strategy)
{
_strategy = strategy;
}
Context::~Context()
{
delete _strategy;
}
void Context::DoAction()
{
_strategy->PrimitiveOperation();
}
//main.cpp
//main.cpp
#include"Context.h"
#include"Strategy.h"
int main()
{
Strategy* p1 = new ConcreteStrategy1();
Strategy* p2 = new ConcreteStrategy2();
Context* c1 = new Context(p1);
Context* c2 = new Context(p2);
c1->DoAction();
c2->DoAction();
return 0;
}
能够看出Template是通过继承来实现接口,儿Strategy模式是通过组合来实现。这两种方式各有优缺点。
继承:长处是易于扩展和改动那些被复用的实现。
缺点有1)破坏了封装,继承父类的实现细节暴露给子类了。2)“白盒”复用,由于1)。3)父类实现更改时,全部子类不得不随之改变。
4)从父类继承而来的实如今执行期间不能改变(编译期间已经确定了。
组合:长处1)“黑盒”复用,封装性好。2)实现和抽象的依赖性低,由于组合对象和被组合对象之间的依赖性非常小。3)能够在执行期间改动,比如通过更改指针指向的对象。
缺点就是系统对象过多。