策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
策略模式里涉及到以下几个角色:
1.Context类,表示应用场景,包含一个策略类的基类指针
2.Strategy类,抽象类,定义了策略类的接口
3.ConcreteStrategy,具体策略类,一般有多个,实现了Strategy定义的接口
策略模式的UML图:
策略模式中每个算法都被封装成了类,可以通过自己的接口单独测试,简化了单元测试,同时避免了程序中过多的条件转移语句,简化了系统并使整个系统易于扩展,遵守了高内聚低耦合的设计原则。但同时,为每一个策略都产生一个类的做法增加了系统中类的个数,并且客户端必须了解这些算法的区别,算法类的选择由客户端负责。
C++实现:
namespace StrategyPattern
{
class Strategy //定义算法类接口
{
public:
virtual ~Strategy(){}
virtual void algorithmInterface() = 0;
};
class Context //算法类的应用场景
{
public:
Context(){}
Context(Strategy *pStrategy) :mPStrategy(pStrategy){}
void setStrategy(Strategy* pStrategy)
{
mPStrategy = pStrategy;
}
void ContextInterface()
{
mPStrategy->algorithmInterface();
}
private:
Strategy *mPStrategy;
};
class ConcreteStrategy1 :public Strategy //具体策略类1
{
public:
~ConcreteStrategy1(){}
void algorithmInterface()
{
cout << "using ConcreteStrategy1" << endl;
}
};
class ConcreteStrategy2 :public Strategy //具体策略类2
{
~ConcreteStrategy2(){}
void algorithmInterface()
{
cout << "using ConcreteStrategy2" << endl;
}
};
class ConcreteStrategy3 :public Strategy //具体策略类3
{
~ConcreteStrategy3(){}
void algorithmInterface()
{
cout << "using ConcreteStrategy3" << endl;
}
};
void test()
{
Context ctt1;
Strategy *s1 = new ConcreteStrategy1();
Strategy *s2 = new ConcreteStrategy2();
Strategy *s3 = new ConcreteStrategy3();
ctt1.setStrategy(s1);
ctt1.ContextInterface();
ctt1.setStrategy(s2);
ctt1.ContextInterface();
ctt1.setStrategy(s3);
ctt1.ContextInterface();
delete s1;
delete s2;
delete s3;
}
}
java代码:
public class Context {
static void process(Strategy sttg )
{
sttg.algorithmsInterface();
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
process(new ConcreteStrategy1());
process(new ConcreteStrategy2());
}
}
interface Strategy
{
void algorithmsInterface();
}
class ConcreteStrategy1 implements Strategy
{
public void algorithmsInterface()
{
System.out.println("ConcreteStrategy1");
}
}
class ConcreteStrategy2 implements Strategy
{
public void algorithmsInterface()
{
System.out.println("ConcreteStrategy2");
}
}