文章目录
- [命令模式(Command Pattern)](#命令模式(Command Pattern))
- [中介者模式(Mediator Pattern)](#中介者模式(Mediator Pattern))
- [观察者模式(Observer Pattern)](#观察者模式(Observer Pattern))
- [状态模式(State Pattern)](#状态模式(State Pattern))
- [策略模式(Strategy Pattern)](#策略模式(Strategy Pattern))
命令模式(Command Pattern)
它将一个请求封装成一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。可以单独执行每一个命令,也可以将命令封装成一个命令宏从而批量执行命令。
UML类图

LightOnCommand、LightOffCommand、FanOnCommand、FanOffCommand与Command是继承关系 ,使用的是空心三角箭头(空心箭头),箭头从子类指向父类。LightOnCommand和LightOffCommand与Light是依赖关系 ,使用的是虚线箭头,箭头指向被依赖对象。FanOnCommand和FanOffCommand与Fan是依赖关系 ,使用的是虚线箭头,箭头指向被依赖对象。MacroCommand与Command是继承关系 ,使用的是空心三角箭头(空心箭头) ,箭头从子类指向父类。同时,MacroCommand与各Command子类是组合关系 ,使用的是实心菱形箭头实线,箭头指向被组合对象。RemoteControl与各Command子类是组合关系 ,使用的是实心菱形箭头实线,箭头指向被组合对象。
代码示例
cpp
#include <iostream>
#include <vector>
#include <stack>
#include <memory>
// 命令接口
class Command {
public:
virtual ~Command() = default;
virtual void execute() = 0;
virtual void undo() = 0; // 支持撤销操作
};
// 接收者1:灯
class Light {
std::string location_;
bool isOn_ = false;
public:
explicit Light(const std::string& location) : location_(location) {}
void on() {
isOn_ = true;
std::cout << location_ << "的灯打开了" << std::endl;
}
void off() {
isOn_ = false;
std::cout << location_ << "的灯关闭了" << std::endl;
}
};
// 接收者2:风扇
class Fan {
std::string location_;
enum Speed { Off, Low, Medium, High };
Speed speed_ = Off;
public:
explicit Fan(const std::string& location) : location_(location) {}
void on() {
speed_ = Low;
std::cout << location_ << "的风扇启动(低速)" << std::endl;
}
void off() {
speed_ = Off;
std::cout << location_ << "的风扇关闭" << std::endl;
}
void setSpeed(Speed speed) {
speed_ = speed;
static const char* speedNames[] = {"关闭", "低速", "中速", "高速"};
std::cout << location_ << "的风扇速度设置为" << speedNames[speed_] << std::endl;
}
Speed getSpeed() const { return speed_; }
};
// 具体命令:打开灯
class LightOnCommand : public Command {
private:
Light* light_;
public:
explicit LightOnCommand(Light* light) : light_(light) {}
void execute() override {
light_->on();
}
void undo() override {
light_->off();
}
};
// 具体命令:关闭灯
class LightOffCommand : public Command {
private:
Light* light_;
public:
explicit LightOffCommand(Light* light) : light_(light) {}
void execute() override {
light_->off();
}
void undo() override {
light_->on();
}
};
// 具体命令:开启风扇低速
class FanOnCommand : public Command {
private:
Fan* fan_;
Fan::Speed prevSpeed_;
public:
explicit FanOnCommand(Fan* fan) : fan_(fan), prevSpeed_(Fan::Off) {}
void execute() override {
prevSpeed_ = fan_->getSpeed();
fan_->on();
}
void undo() override {
fan_->setSpeed(prevSpeed_);
}
};
// 具体命令:关闭风扇
class FanOffCommand : public Command {
private:
Fan* fan_;
Fan::Speed prevSpeed_;
public:
explicit FanOffCommand(Fan* fan) : fan_(fan), prevSpeed_(Fan::Off) {}
void execute() override {
prevSpeed_ = fan_->getSpeed();
fan_->off();
}
void undo() override {
fan_->setSpeed(prevSpeed_);
}
};
// 宏命令,执行一组命令
class MacroCommand : public Command {
private:
std::vector<std::shared_ptr<Command>> commands_;
public:
void add(const std::shared_ptr<Command>& command) {
commands_.push_back(command);
}
void execute() override {
for (auto& cmd : commands_) {
cmd->execute();
}
}
void undo() override {
// 逆序撤销
for (auto it = commands_.rbegin(); it != commands_.rend(); ++it) {
(*it)->undo();
}
}
};
// 调用者 - 遥控器
class RemoteControl {
private:
std::stack<std::shared_ptr<Command>> history_; // 支持撤销的命令历史栈
public:
void submitCommand(const std::shared_ptr<Command>& cmd) {
cmd->execute();
history_.push(cmd);
}
void undo() {
if (!history_.empty()) {
auto cmd = history_.top();
cmd->undo();
history_.pop();
} else {
std::cout << "没有命令可以撤销" << std::endl;
}
}
};
int main() {
Light livingRoomLight("客厅");
Fan ceilingFan("客厅");
RemoteControl remote;
// 创建灯的打开关闭命令
auto lightOn = std::make_shared<LightOnCommand>(&livingRoomLight);
auto lightOff = std::make_shared<LightOffCommand>(&livingRoomLight);
// 创建风扇的开、关命令
auto fanOn = std::make_shared<FanOnCommand>(&ceilingFan);
auto fanOff = std::make_shared<FanOffCommand>(&ceilingFan);
// 单独打开灯
remote.submitCommand(lightOn);
// 单独关闭灯
remote.submitCommand(lightOff);
// 打开风扇
remote.submitCommand(fanOn);
// 撤销风扇开启
remote.undo();
// 创建宏命令,打开灯和风扇
auto partyOn = std::make_shared<MacroCommand>();
partyOn->add(lightOn);
partyOn->add(fanOn);
// 创建宏命令,关闭灯和风扇
auto partyOff = std::make_shared<MacroCommand>();
partyOff->add(lightOff);
partyOff->add(fanOff);
// 执行宏命令
std::cout << "\n开启派对模式:" << std::endl;
remote.submitCommand(partyOn);
// 撤销宏命令
std::cout << "\n撤销派对模式:" << std::endl;
remote.undo();
// 关闭派对模式
std::cout << "\n关闭派对模式:" << std::endl;
remote.submitCommand(partyOff);
return 0;
}
- 这里的RemoteControl 和MacroCommand并不是必须的引入的目的主要是做管理和回滚命令。
- MacroCommand属于将多个Command组合成一系列动作,因此,它既继承了Command又依赖Command子类运行。
中介者模式(Mediator Pattern)
它通过引入一个中介者对象来封装一组对象之间的交互,使各个对象不需要显式地相互引用,从而降低对象之间的耦合度,提高系统的灵活性和可维护性。例如:有一个聊天室系统,多个用户发送消息,不直接发送给彼此,而是通过聊天室(中介者)转发消息。
UML类图

ChatMediator与ChatRoom是继承关系 ,使用的是空心三角箭头(空心箭头),箭头从子类指向父类。User与ConcreteUser是继承关系 ,使用的是空心三角箭头(空心箭头),箭头从子类指向父类。ConcreteUser与ChatRoom是依赖关系 ,使用的是虚线箭头,箭头指向被依赖对象。
代码示例
cpp
#include <iostream>
#include <string>
#include <vector>
#include <memory>
// 抽象中介者
class ChatMediator {
public:
virtual void sendMessage(const std::string& msg, int userId) = 0;
virtual void addUser(int userId) = 0;
virtual ~ChatMediator() = default;
};
// 具体中介者
class ChatRoom : public ChatMediator {
private:
std::vector<int> users; // 简化用户存储,只存用户ID
public:
void sendMessage(const std::string& msg, int userId) override {
for (int id : users) {
if (id != userId) {
std::cout << "User" << id << " received: " << msg << std::endl;
}
}
}
void addUser(int userId) override {
users.push_back(userId);
}
};
// 抽象同事类
class User {
protected:
ChatMediator& mediator;
int id;
public:
User(ChatMediator& m, int uid) : mediator(m), id(uid) {
mediator.addUser(id);
}
virtual void send(const std::string& msg) = 0;
virtual void receive(const std::string& msg) {
std::cout << "User" << id << " received: " << msg << std::endl;
}
virtual ~User() = default;
};
// 具体同事类
class ConcreteUser : public User {
public:
ConcreteUser(ChatMediator& m, int uid) : User(m, uid) {}
void send(const std::string& msg) override {
std::cout << "User" << id << " sends: " << msg << std::endl;
mediator.sendMessage(msg, id);
}
};
int main() {
ChatRoom chatroom;
ConcreteUser user1(chatroom, 1);
ConcreteUser user2(chatroom, 2);
ConcreteUser user3(chatroom, 3);
user1.send("Hello, everyone!");
user2.send("Hi User1!");
user3.send("Good morning!");
return 0;
}
观察者模式(Observer Pattern)
是一种常用的软件设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。
UML类图

CurrentConditionsDisplay、StatisticsDisplay与Observer是继承关系 ,使用的是空心三角箭头(空心箭头),箭头从子类指向父类。WeatherData与Subject是继承关系 ,使用的是空心三角箭头(空心箭头),箭头从子类指向父类。Subject子类与各Observer子类是依赖关系 ,使用的是虚线箭头,箭头指向被依赖对象。
代码示例
cpp
#include <iostream>
#include <vector>
#include <algorithm>
// 抽象观察者
class Observer {
public:
virtual ~Observer() = default;
virtual void update(float temperature, float humidity) = 0;
};
// 抽象主题
class Subject {
public:
virtual ~Subject() = default;
virtual void registerObserver(Observer* observer) = 0;
virtual void removeObserver(Observer* observer) = 0;
virtual void notifyObservers() = 0;
};
// 具体主题------天气数据
class WeatherData : public Subject {
private:
std::vector<Observer*> observers;
float temperature;
float humidity;
public:
void registerObserver(Observer* observer) override {
observers.push_back(observer);
}
void removeObserver(Observer* observer) override {
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notifyObservers() override {
for (Observer* observer : observers) {
observer->update(temperature, humidity);
}
}
// 当天气数据更新时调用此方法
void setMeasurements(float temp, float hum) {
temperature = temp;
humidity = hum;
notifyObservers();
}
};
// 具体观察者------显示设备1
class CurrentConditionsDisplay : public Observer {
private:
float temperature;
float humidity;
public:
void update(float temp, float hum) override {
temperature = temp;
humidity = hum;
display();
}
void display() {
std::cout << "Current conditions: " << temperature << "°C and " << humidity << "% humidity\n";
}
};
// 具体观察者------显示设备2
class StatisticsDisplay : public Observer {
private:
float maxTemp = -1000;
float minTemp = 1000;
float tempSum = 0;
int numReadings = 0;
public:
void update(float temp, float hum) override {
tempSum += temp;
numReadings++;
if (temp > maxTemp) maxTemp = temp;
if (temp < minTemp) minTemp = temp;
display();
}
void display() {
std::cout << "Avg/Max/Min temperature = " << (tempSum / numReadings)
<< "/" << maxTemp << "/" << minTemp << "\n";
}
};
int main() {
WeatherData weatherData;
CurrentConditionsDisplay currentDisplay;
StatisticsDisplay statsDisplay;
// 注册观察者
weatherData.registerObserver(¤tDisplay);
weatherData.registerObserver(&statsDisplay);
// 模拟数据变化
weatherData.setMeasurements(25.0f, 65.0f);
weatherData.setMeasurements(27.0f, 70.0f);
weatherData.setMeasurements(23.0f, 90.0f);
// 移除观察者后数据变化
weatherData.removeObserver(¤tDisplay);
weatherData.setMeasurements(26.0f, 80.0f);
return 0;
}
状态模式(State Pattern)
将对象的状态封装到独立的状态类中,并通过状态类切换来改变对象的行为。这样即使状态变化导致行为变化,也不会引起客户端代码的改变,这个设计模式最典型的是TCP连接过程。
UML类图

ClosedState、ListenState、EstablishedState与TcpState是继承关系 ,使用的是空心三角箭头(空心箭头),箭头从子类指向父类。TcpConnection与各TcpState子类是依赖关系 ,使用的是虚线箭头,箭头指向被依赖对象。
代码示例
cpp
#include <iostream>
#include <memory>
// 前向声明
class TcpState;
// 环境类
class TcpConnection {
public:
TcpConnection(std::shared_ptr<TcpState> state) : state_(state) {}
void setState(std::shared_ptr<TcpState> state) {
state_ = state;
}
void open() {state_->open(*this);}
void close() {state_->close(*this);}
void acknowledge() {state_->acknowledge(*this);}
private:
std::shared_ptr<TcpState> state_;
};
// 抽象状态接口
class TcpState {
public:
virtual ~TcpState() = default;
virtual void open(TcpConnection& connection) = 0;
virtual void close(TcpConnection& connection) = 0;
virtual void acknowledge(TcpConnection& connection) = 0;
};
// 具体状态:Closed
class ClosedState : public TcpState {
public:
void open(TcpConnection& connection) override {
std::cout << "打开连接,进入监听状态\n";
connection.setState(std::make_shared<ListenState>());
}
void close(TcpConnection& /*connection*/) override {
std::cout << "连接已经关闭\n";
}
void acknowledge(TcpConnection& /*connection*/) override {
std::cout << "连接关闭,无法接收确认\n";
}
};
// 具体状态:Listen
class ListenState : public TcpState {
public:
void open(TcpConnection& connection) override {
std::cout << "连接建立,进入已建立状态\n";
connection.setState(std::make_shared<EstablishedState>());
}
void close(TcpConnection& connection) override {
std::cout << "关闭连接,进入关闭状态\n";
connection.setState(std::make_shared<ClosedState>());
}
void acknowledge(TcpConnection& /*connection*/) override {
std::cout << "监听状态,等待连接建立\n";
}
};
// 具体状态:Established
class EstablishedState : public TcpState {
public:
void open(TcpConnection& /*connection*/) override {
std::cout << "连接已建立,不能重新打开\n";
}
void close(TcpConnection& connection) override {
std::cout << "关闭连接,进入关闭状态\n";
connection.setState(std::make_shared<ClosedState>());
}
void acknowledge(TcpConnection& /*connection*/) override {
std::cout << "接收确认数据\n";
}
};
// 测试主函数
int main() {
auto closed = std::make_shared<ClosedState>();
TcpConnection connection(closed);
connection.open(); // Closed -> Listen
connection.acknowledge(); // Listen状态,等待连接建立
connection.open(); // Listen -> Established
connection.acknowledge(); // Established 接收确认数据
connection.close(); // Established -> Closed
connection.close(); // 已关闭状态,无法关闭
return 0;
}
策略模式(Strategy Pattern)
它定义了一系列算法,把它们一个个封装起来,并使它们可以互相替换。策略模式让算法独立于使用它的客户而变化。策略模式的核心意图:
- 将算法族封装起来,使它们可以互换。
- 策略模式让算法独立于使用它的客户端独立变化。
- 客户端在运行时可以自由选择具体策略实现。
UML类图

NoDiscount、FullReduction、PercentageDiscount与DiscountStrategy是继承关系 ,使用的是空心三角箭头(空心箭头),箭头从子类指向父类。ShoppingCarts与各DiscountStrategy子类是依赖关系 ,使用的是虚线箭头,箭头指向被依赖对象。
代码示例
cpp
#include <iostream>
#include <memory>
// 抽象策略类
class DiscountStrategy {
public:
virtual ~DiscountStrategy() = default;
virtual double calculate(double price) const = 0;
};
// 具体策略类 - 无折扣
class NoDiscount : public DiscountStrategy {
public:
double calculate(double price) const override {
return price;
}
};
// 具体策略类 - 满减(如满100减20)
class FullReduction : public DiscountStrategy {
public:
double calculate(double price) const override {
if (price >= 100.0)
return price - 20.0;
return price;
}
};
// 具体策略类 - 打折(如打8折)
class PercentageDiscount : public DiscountStrategy {
public:
PercentageDiscount(double discount) : discount_(discount) {}
double calculate(double price) const override {
return price * discount_;
}
private:
double discount_; // 0.8 表示打8折
};
// 上下文类
class ShoppingCart {
public:
void setDiscountStrategy(std::shared_ptr<DiscountStrategy> strategy) {
strategy_ = strategy;
}
double calculatePrice(double price) const {
if (strategy_) {
return strategy_->calculate(price);
}
return price; // 默认无折扣
}
private:
std::shared_ptr<DiscountStrategy> strategy_;
};
int main() {
ShoppingCart cart;
double originalPrice = 120.0;
std::cout << "原价: " << originalPrice << "\n";
// 使用无折扣策略
cart.setDiscountStrategy(std::make_shared<NoDiscount>());
std::cout << "无折扣价: " << cart.calculatePrice(originalPrice) << "\n";
// 使用满减策略
cart.setDiscountStrategy(std::make_shared<FullReduction>());
std::cout << "满减价: " << cart.calculatePrice(originalPrice) << "\n";
// 使用打折策略(8折)
cart.setDiscountStrategy(std::make_shared<PercentageDiscount>(0.8));
std::cout << "打折价: " << cart.calculatePrice(originalPrice) << "\n";
return 0;
}