策略模式(Strategy Pattern)属于对象的行为模式。
其用意是针对一组算法(类的一组行为),将每一个算法封装到具有共同接口的独立的类中(将变与不变的部分彼此分离,各自独立互不影响),从而使得它们在运行过程可以相互变化。
假设现有一个Duck类,有相同的行为,比如quack()、swim();同时不同的Duck类表现出不同的行为,比如不同的Duck类的display()的外观颜色不同、有的Duck会fly(),然而有的不会。同时要求在运行的过程中改变Duck类的某些行为,比如颜色从红色变为白色。
类图:
聚合(Aggregation):聚合的整体和部分之间在生命周期上没有什么必然的联系,部分对象可以在整体对象创建之前创建,也可以在整体对象销毁之后销毁。
一般用带一个空心菱形(整体的一端)的实线表示。
组合(Composition):它强调了整体与部分的生命周期是一致的。
一般用带实心菱形(整体的一端)的实线来表示。
代码如下:
duck.h:
#ifndef DUCK_H
#define DUCK_H
#include "displayBehavior.h"
#include "redBehavior.h"
#include "whiteDisplay.h"
class Duck {
public:
// 共同的行为
void quack();
void swim();
public:
// 动态改变行为
void setRedBehavior();
void setWhiteBehavior();
public:
DisplayBehavior *dis; // 面向接口编程
};
void Duck::quack()
{
cout << "鸭子叫" << endl;
}
void Duck::swim()
{
cout << "鸭子游泳" << endl;
}
void Duck::setRedBehavior()
{
dis = new RedBehavior();
}
void Duck::setWhiteBehavior()
{
dis = new WhiteDisplay();
}
#endif // DUCK_H
redDuck.h:
#ifndef REDDUCK_H
#define REDDUCK_H
#include "duck.h"
class RedDuck : public Duck {
public:
RedDuck();
};
RedDuck::RedDuck()
{
dis = new RedBehavior();
}
#endif // REDDUCK_H
displayBehavior.h:
#ifndef DISPLAYBEHAVIOR_H
#define DISPLAYBEHAVIOR_H
#include <iostream>
using namespace std;// 实际开发中不建议
class DisplayBehavior {
public:
virtual void display() = 0; // 纯虚函数,提供接口
};
#endif // DISPLAYBEHAVIOR_H
redBehavior.h:
#ifndef REDBEHAVIOR_H
#define REDBEHAVIOR_H
#include "displayBehavior.h"
class RedBehavior : public DisplayBehavior {
virtual void display() override final;
};
void RedBehavior::display()
{
cout << "外观是红色" << endl;
}
#endif // REDBEHAVIOR_H
whiteBehavior.h:
#ifndef WHITEDISPLAY_H
#define WHITEDISPLAY_H
#include "displayBehavior.h"
class WhiteDisplay : public DisplayBehavior {
virtual void display() override final;
};
void WhiteDisplay::display()
{
cout << "外观是白色" << endl;
}
#endif // WHITEDISPLAY_H
main.cpp:
/*
* 策略模式
*
* date:2023-9-4
*/
#include "redDuck.h"
int main()
{
cout << "红色鸭子" << endl;
RedDuck rd;
rd.quack();
rd.swim();
rd.dis->display();
cout << "\n红色鸭子改变成白色鸭子\n" << endl;
rd.setWhiteBehavior();
rd.dis->display();
}
运行结果: