模式定义
策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
策略模式的优点
策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
策略模式提供了管理相关的算法族的办法。
策略模式提供了可以替换继承关系的办法。
使用策略模式可以避免使用多重条件转移语句。
策略模式的缺点
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。
适用环境
在以下情况下可以使用策略模式:
如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
一个系统需要动态地在几种算法中选择一种。
如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法和相关的数据结构,提高算法的保密性与安全性。
参考:
http://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/strategy.html
C++实现源码
#include<bits/stdc++.h>
using namespace std;
class FlyBehavior{
public:
FlyBehavior(){}
virtual ~FlyBehavior(){}
virtual void fly() = 0;
};
class QuackBehavior{
public:
QuackBehavior(){}
virtual ~QuackBehavior(){}
virtual void quack() = 0;
};
class Duck{
public:
Dock(){}
virtual ~Duck(){}
FlyBehavior *flyBehavior;
QuackBehavior *quackBehavior;
virtual void display(){}
void performFly() {
flyBehavior->fly();
}
void performQuack() {
quackBehavior->quack();
}
void setFlyBehavior(FlyBehavior *fb) {
flyBehavior = fb;
}
void setQuackBehavior(QuackBehavior *qb) {
quackBehavior = qb;
}
void swim() {
cout<< "All ducks float, even decoys!"<<endl;
}
};
class FlyWithSwings : public FlyBehavior{
public:
void fly() {
cout<<"I can fly! Hahaha……"<<endl;
}
};
class FlyNoWay : public FlyBehavior{
public:
void fly() {
cout<< "I can't fly, and I'm so foolish!"<<endl;
}
};
class FlyRocketPowered : public FlyBehavior{
public:
FlyRocketPowered(){}
~FlyRocketPowered(){}
void fly() {
cout<<"I'm flying with a rocket!"<<endl;
}
} ;
class Quack : public QuackBehavior{
public:
void quack() {
cout<<"Quack, Gua, Gua, Gua!"<<endl;
}
};
class MeteQuack : public QuackBehavior{
public:
void quack() {
cout<<"<Silence!>"<<endl;
}
};
class Squeak : public QuackBehavior {
public:
void quack() {
cout<<"Squeak, Squeak!"<<endl;
}
};
class MallardDuck : public Duck{
public:
MallardDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyWithSwings();
}
~MallardDuck(){}
void display() {
cout<<"I'm a real Mallard duck"<<endl;
}
};
class RubberDuck : public Duck{
public:
RubberDuck() {
flyBehavior = new FlyNoWay();
quackBehavior = new Squeak();
}
~RubberDuck () {}
void display() {
cout<<"I'm a RubberDuck!"<<endl;
}
};
//duckcall
class DuckCall : public QuackBehavior{
public:
DuckCall(){}
~DuckCall(){}
QuackBehavior *quackBehavior;
void SetQuackBehavior(QuackBehavior *qb) {
quackBehavior = qb;
}
void quack() {
quackBehavior->quack();
}
};
int main() {
Duck *duck = new MallardDuck();
duck->display();
duck->performFly();
duck->performQuack();
delete duck;
duck = nullptr;
duck = new RubberDuck();
duck->display();
duck->performQuack();
duck->performFly();
duck->setFlyBehavior(new FlyRocketPowered());
duck->performFly();
delete duck;
duck = nullptr;
DuckCall *duckCall = new DuckCall();
duckCall->SetQuackBehavior(new Quack());
duckCall->quack();
return 0;
}