策略模式
定义一系列算法,分别封装,并且使他们可以相互替换(变化)。该模式使得算法「独立」于使用他的客户程序(稳定)而变化。
动机
软件构造过程中,某些对象使用的算法多种多样,经常改变。如果将算法都编码到对象中,会使得对象异常复杂且冗余。
策略模式能够在运行时根据需求透明的更改对象的算法,将算法与对象解耦合。
适用场景
1、如果在一个系统里由很多类,而这些类之间的区别仅是行为不同,那就需要用策略模式来让对象动态的在许多行为中选择一个行为。
2、一个系统需要动态的在几种算法中选择一种。
3、如果一个对象有很多的行为,如果使用不恰当的模式,这些行为就只好使用多重的条件语句来实现。
实例
1、鸭子游戏;
2、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。
3、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
优点:
1、算法可以自由切换 。
2、避免使用多重条件判断 。
3、扩展性好。
缺点
1、策略类会很多。
2、所有策略类都需要对外暴露。
结构图
代码
#pragma once
// -----------------------策略模式-------------------------
// 策略基类
class Strategy {
public:
virtual void algorithm() = 0;
};
class Factory {
public:
virtual Strategy* mopNewStrategy() = 0;
};
// 策略1
class Strategy1 : public Strategy {
public:
virtual void algorithm() {}
};
class Factory1 : public Factory {
public:
virtual Strategy* mopNewStrategy() { return new Strategy1; }
};
// 策略2
class Strategy2 : public Strategy {
public:
virtual void algorithm() {}
};
class Factory2 : public Factory {
public:
virtual Strategy* mopNewStrategy() { return new Strategy2; }
};
// ---------- 变化 ----------
// 策略3
class Strategy3 : public Strategy {
public:
virtual void algorithm() {}
};
class Factory3 : public Factory {
public:
virtual Strategy* mopNewStrategy() { return new Strategy3; }
};
// ---------- 稳定 ----------
class Context {
public:
Context(Factory* opFactory) {
mopStrategy = opFactory->mopNewStrategy(); // 动态创建策略对象
}
void contextFunc() {
mopStrategy->algorithm(); // 动态执行策略对应算法
}
private:
Strategy* mopStrategy;
};
// -------------------------
void test() {
// 策略1
Factory1 f1;
Context c1(&f1);
// 策略1
Factory2 f2;
Context c2(&f2);
// 变化:策略3
Factory3 f3;
Context c3(&f3);
}