1 概念
策略模式(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.)
2 策略模式的结构
封装类:也叫上下文,对策略进行二次封装,目的是避免高层模块对策略的直接调用。
抽象策略:通常情况下为一个接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。
具体策略:具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。
3 设计原则
[color=red][size=large] a) 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起;
b) 针对借口编程,而不是针对实现编程;
c) 多用组合,少用继承;
d) 含有许多条件语句(if-else)的代码意味着需要使用Strategy模式[/size][/color]
[img]http://t25-3.yunpan.360.cn/p/800-600.8be37e5343f6a0c4f5db05fd60622230b545a1cd.269302.jpg?t=a344bfb34b846467f2df389c48ad5ce8&d=20130821[/img]
示例代码:
[b]Java代码示例[/b]
策略模式(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.)
2 策略模式的结构
封装类:也叫上下文,对策略进行二次封装,目的是避免高层模块对策略的直接调用。
抽象策略:通常情况下为一个接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。
具体策略:具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。
3 设计原则
[color=red][size=large] a) 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起;
b) 针对借口编程,而不是针对实现编程;
c) 多用组合,少用继承;
d) 含有许多条件语句(if-else)的代码意味着需要使用Strategy模式[/size][/color]
[img]http://t25-3.yunpan.360.cn/p/800-600.8be37e5343f6a0c4f5db05fd60622230b545a1cd.269302.jpg?t=a344bfb34b846467f2df389c48ad5ce8&d=20130821[/img]
示例代码:
#ifndef STRATEGY_H
#define STRATEGY_H
#include <iostream>
using namespace std;
//策略模式
namespace Strategy
{
//
class FlyBehavior
{
public:
virtual void fly() = 0;
};
class FlyWithWings : public FlyBehavior
{
public:
virtual void fly() { cout << "I'm flying!!" << endl; }
};
class FlyNoWay : public FlyBehavior
{
public:
virtual void fly() { cout << "I can't fly!" << endl; }
};
class FlyRocketPowred : public FlyBehavior
{
public:
virtual void fly() { cout << "I'm flying with a rocket!" << endl; }
};
//
class QuackBehavior
{
public:
virtual void quack() = 0;
};
class Quack : public QuackBehavior
{
public:
virtual void quack() { cout << "Quack" << endl;}
};
class MuteQuack : public QuackBehavior
{
public:
virtual void quack() { cout << "<<Silence>>" << endl; }
};
class Squack : public QuackBehavior
{
public:
virtual void quack() { cout << "Squack" << endl;}
};
//
class Duck
{
public:
Duck(){}
virtual ~Duck(){}
virtual void display() = 0;
virtual void performFly()
{
if ( m_FlyBehavior != NULL)
{
m_FlyBehavior->fly();
}
}
virtual void performQuack()
{
if ( m_QuackBehavior != NULL)
{
m_QuackBehavior->quack();
}
}
virtual void swim() { cout << "All ducks float, even decoys!" <<endl; }
virtual void setFlyBehavior(FlyBehavior* fb)
{
if (fb != NULL)
{
delete m_FlyBehavior;
m_FlyBehavior = fb;
}
}
virtual void setQuackBehavior(QuackBehavior* qb)
{
if (qb != NULL)
{
delete m_QuackBehavior;
m_QuackBehavior = qb;
}
}
protected:
FlyBehavior* m_FlyBehavior;
QuackBehavior* m_QuackBehavior;
};
class MallardDuck : public Duck
{
public:
MallardDuck()
{
m_QuackBehavior = new Quack();
m_FlyBehavior = new FlyWithWings();
}
virtual ~MallardDuck()
{
if (m_FlyBehavior != NULL)
{
delete m_FlyBehavior;
m_FlyBehavior = NULL;
}
if (m_QuackBehavior != NULL)
{
delete m_QuackBehavior;
m_QuackBehavior = NULL;
}
}
virtual void display() { cout << "I'm a real Mallard duck" << endl; }
};
class ModelDuck : public Duck
{
public:
ModelDuck()
{
m_FlyBehavior = new FlyNoWay();
m_QuackBehavior = new Quack();
}
virtual ~ModelDuck()
{
if (m_FlyBehavior != NULL)
{
delete m_FlyBehavior;
m_FlyBehavior = NULL;
}
if (m_QuackBehavior != NULL)
{
delete m_QuackBehavior;
m_QuackBehavior = NULL;
}
}
virtual void display()
{
cout << "I'm a model duck" << endl;
}
};
//
class MiniDuckSimulator
{
public:
void run()
{
//UnitTest1
Duck* pMallard = new MallardDuck();
pMallard->performQuack();
pMallard->performFly();
delete pMallard;
//UnitTest2
Duck* pModel = new ModelDuck();
pModel->performFly();
pModel->setFlyBehavior(new FlyRocketPowred());
pModel->performFly();
delete pModel;
}
};
}//namespace Strategy
#endif
[b]Java代码示例[/b]
//1 Quack Behavior
///
public interface QuackBehavior{
public void quack();
}
public class MuteQuack implements QuackBehavior{
public void quack(){
System.out.println("<< silence >>");
}
}
public class Quack implements QuackBehavior{
public void quack(){
System.out.println("Quack");
}
}
public class Squeak implements QuackBehavior{
public void quack(){
System.out.println("Squeak");
}
}
//2 Fly Behavior
///
public interface FlyBehavior{
public void fly();
}
public class FlyNoWay implements FlyBehavior{
public void fly(){
System.out.println("I can't fly!");
}
}
public class FlyWithWings implements FlyBehavior{
public void fly(){
System.out.println("I'm flying!");
}
}
public class FlyRocketPowered implements FlyBehavior{
public void fly(){
System.out.println("I'm flying with a rocket!");
}
}
//3 Duck
///
public abstract class Duck{
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck(){
}
public abstract void display();
public void performFly(){
flyBehavior.fly();
}
public void performQuack(){
quackBehavior.quack();
}
public void swim(){
System.out.println("All ducks float, even decoys!");
}
public void setFlyBehavior(FlyBehavior fb){
flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb){
quackBehavior = qb;
}
}
public class MallardDuck extends Duck{
public MallardDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
public void display(){
System.out.println("I'm a real Mallard duck");
}
}
public class ModelDuck extends Duck{
public ModelDuck(){
flyBehavior = new FlyNoWay();
quackBehavior = new Quack();
}
public void display(){
System.out.println("I'm a model duck");
}
}
//4 Test Simulator
///
public class MiniDuckSimulator{
public static void main(String[] args){
Duck mallard = new MallardDuck();
mallard.performQuack();
mallard.performFly();
Duck model = new ModelDuck();
model.performFly();
model.setFlyBehavior(new FlyRocketPowered());
model.performFly();
}
}
C:\Users\jacky_dai\Desktop>java MiniDuckSimulator
Quack
I'm flying!
I can't fly!
I'm flying with a rocket!
请按任意键继续. . .