1. 模式说明
策略模式(strategy), 它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
2. uml图例
3. 示例代码
在 《Head First设计模式》中实现了一个鸭子的案例。鸭子的方法有swim, fly(), quack(),display(). 但不同的鸭子fly 和 quack的方式不同。
fly 和 quack的形式也可能随时都在变化。如果采用继承,就无法改变。所以采用组合。首先创建Duck 类,再创建FlyBahivior和QuackBahivior类,
让Duck 类拥有FlyBahivior和QuackBahivior类. 详细代码如下:
//"Strategy.h"/
#ifndef STRATEGY_H
#define STRATEGY_H
#include <iostream>
using namespace std;
class FlyBehavior;
class QuackBehavior;
//使用默认构造函数
class Duck
{
public:
Duck();
void Swim();
virtual void Display();
void PerformQuack();
void PerformFly();
void SetFlyBehavior(FlyBehavior *pFlyBehavior);
void SetQuackBehavior(QuackBehavior *pQuackBehavior);
private:
//优先使用组合,而不是继承
FlyBehavior *m_pFlyBehavior;
QuackBehavior *m_pQuackBehavior;
};
class MallardDuck : public Duck
{
public:
void display();
};
class RedHeadDuck: public Duck
{
public:
void display();
};
class RubberDuck: public Duck
{
public:
void display();
};
class DecoyDuck: public Duck
{
public:
void display();
};
class FlyBehavior
{
public:
virtual void Fly() = 0;
};
class FlyWithWings: public FlyBehavior
{
public:
void Fly();
};
class FlyNoWay: public FlyBehavior
{
public:
void Fly();
};
class QuackBehavior
{
public:
virtual void Quack() = 0;
};
class NormalQuack: public QuackBehavior
{
public:
void Quack();
};
class SQuack: public QuackBehavior
{
public:
void Quack();
};
class MuteQuack: public QuackBehavior
{
public:
void Quack();
};
#endif // STRATEGY_H
//"Strategy.cpp"/
#include "Strategy.h"
Duck::Duck()
{
m_pFlyBehavior = nullptr;
m_pQuackBehavior = nullptr;
}
void Duck::Swim()
{
cout << "Duck Swim" << endl;
}
void Duck::Display()
{
cout << "Duck Swim" << endl;
}
void Duck::PerformQuack()
{
m_pQuackBehavior->Quack();
}
void Duck::PerformFly()
{
m_pFlyBehavior->Fly();
}
void Duck::SetFlyBehavior(FlyBehavior *pFlyBehavior)
{
m_pFlyBehavior = pFlyBehavior;
}
void Duck::SetQuackBehavior(QuackBehavior *pQuackBehavior)
{
m_pQuackBehavior = pQuackBehavior;
}
void MallardDuck::display()
{
cout << "MallardDuck display" << endl;
}
void RedHeadDuck::display()
{
cout << "RedHeadDuck display" << endl;
}
void RubberDuck::display()
{
cout << "RubberDuck display" << endl;
}
void DecoyDuck::display()
{
cout << "DecoyDuck display" << endl;
}
void FlyWithWings::Fly()
{
cout << "FlyWithWings fly" << endl;
}
void FlyNoWay::Fly()
{
cout << "FlyNoWay fly" << endl;
}
void NormalQuack::Quack()
{
cout << "NormalQuack Quack" << endl;
}
void SQuack::Quack()
{
cout << "SQuack Quack" << endl;
}
void MuteQuack::Quack()
{
cout << "MuteQuack Quack" << endl;
}
//"main.cpp"/
Duck *duck_mallard = new MallardDuck();
duck_mallard->Display();
FlyBehavior *fb1 = new FlyNoWay();
duck_mallard->SetFlyBehavior(fb1);
duck_mallard->PerformFly();
QuackBehavior *qb1 = new NormalQuack();
duck_mallard->SetQuackBehavior(qb1);
duck_mallard->PerformQuack();
cout << "change fly & quack method." << endl;
FlyBehavior *fb2 = new FlyWithWings();
duck_mallard->SetFlyBehavior(fb2);
duck_mallard->PerformFly();
QuackBehavior *qb2 = new SQuack();
duck_mallard->SetQuackBehavior(qb2);
duck_mallard->PerformQuack();
执行结果后,fly 和quack 能够动态的修改。
4. 参考文献
1) 《大话设计模式》作者:程杰, 清华大学出版社。
2) 《Head First设计模式》 作者 Eric Freeman & Elisabeth Freeman, 中国电力出版社
3) 《面向对象葵花宝典:思想、技巧与实践》 作者:李运华,电子工业出版社