1. 单例模式 (Singleton)
这是 C++ 中使用频率极高的模式。
作用: 确保一个类只有一个实例,并提供一个全局访问点。
应用场景: 日志管理器、配置管理器、线程池、数据库连接池。
C++ 注意点: 需要特别注意线程安全。C++11 及以后,推荐使用"局部静态变量"实现(Meyers Singleton),由编译器保证线程安全,代码简洁且无需手动加锁
代码举例:
cpp
#include <iostream>
#include <string>
class ConfigManager {
public:
// 获取唯一实例的接口
static ConfigManager& getInstance() {
// C++11 保证静态局部变量初始化是线程安全的
static ConfigManager instance;
return instance;
}
// 删除拷贝构造和赋值操作,防止意外复制
ConfigManager(const ConfigManager&) = delete;
ConfigManager& operator=(const ConfigManager&) = delete;
void setConfig(const std::string& key, const std::string& value) {
std::cout << "设置配置: " << key << " = " << value << std::endl;
// 实际存储逻辑...
}
private:
// 私有构造函数和析构函数
ConfigManager() { std::cout << "配置管理器初始化\n"; }
~ConfigManager() { std::cout << "配置管理器销毁\n"; }
};
// --- 使用示例 ---
int main() {
// 获取实例 (无论调用多少次,都是同一个对象)
auto& config1 = ConfigManager::getInstance();
auto& config2 = ConfigManager::getInstance();
// 地址相同,证明是同一个实例
std::cout << &config1 << " == " << &config2 << std::endl;
config1.setConfig("Volume", "80%");
return 0;
}
2. 工厂模式 (Factory)
用于解耦对象的创建过程,主要包含两种变体:
简单工厂 (Simple Factory): 通过传入参数决定创建哪种具体产品。虽然常用,但增加新产品时需要修改工厂类,违反开闭原则。
工厂方法 (Factory Method): 定义一个创建对象的接口,但让子类决定实例化哪一个类(如 Creator 类派生出 ConcreteCreator)。
应用场景: 游戏中的角色生成器、不同数据库驱动的连接创建
代码举例:
cpp
#include <iostream>
#include <memory>
// 产品接口
class Product {
public:
virtual ~Product() = default;
virtual void use() = 0;
};
// 具体产品 A
class ConcreteProductA : public Product {
public:
void use() override {
std::cout << "使用产品 A\n";
}
};
// 具体产品 B
class ConcreteProductB : public Product {
public:
void use() override {
std::cout << "使用产品 B\n";
}
};
// 工厂接口
class Factory {
public:
virtual ~Factory() = default;
// 工厂方法:返回一个产品对象
virtual std::unique_ptr<Product> createProduct() = 0;
};
// 具体工厂 A
class ConcreteFactoryA : public Factory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ConcreteProductA>();
}
};
// --- 使用示例 ---
int main() {
// 创建工厂 A
ConcreteFactoryA factoryA;
// 通过工厂创建产品 (客户端不需要知道具体的产品类名)
auto product = factoryA.createProduct();
product->use(); // 输出: 使用产品 A
return 0;
}
3. 观察者模式 (Observer)
作用: 定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会收到通知。
应用场景: 事件处理系统、MVC 架构中的视图更新、发布-订阅模型
cpp
#include <iostream>
#include <vector>
#include <algorithm>
// 观察者接口
class Observer {
public:
virtual ~Observer() = default;
virtual void update(const std::string& message) = 0;
};
// 被观察者 (主题)
class Subject {
private:
std::vector<Observer*> observers; // 观察者列表
std::string state;
public:
void attach(Observer* o) {
observers.push_back(o);
}
void detach(Observer* o) {
observers.erase(
std::remove(observers.begin(), observers.end(), o),
observers.end()
);
}
// 状态改变,通知所有观察者
void setState(const std::string& s) {
state = s;
notify();
}
void notify() {
for (auto* obs : observers) {
obs->update(state);
}
}
};
// 具体观察者
class ConcreteObserver : public Observer {
private:
std::string name;
public:
ConcreteObserver(const std::string& n) : name(n) {}
void update(const std::string& message) override {
std::cout << name << " 收到通知: " << message << std::endl;
}
};
// --- 使用示例 ---
int main() {
Subject weatherStation; // 气象站
ConcreteObserver user1("用户A");
ConcreteObserver user2("用户B");
// 用户订阅气象站
weatherStation.attach(&user1);
weatherStation.attach(&user2);
// 气象站发布消息,所有订阅者收到
weatherStation.setState("今天天气晴朗");
// 输出:
// 用户A 收到通知: 今天天气晴朗
// 用户B 收到通知: 今天天气晴朗
return 0;
}
4. 策略模式 (Strategy)
作用: 将算法封装在独立的类中,使它们可以互相替换。客户端可以在运行时选择不同的策略。
应用场景: 支付方式的选择(微信、支付宝)、排序算法的切换。它有助于消除大量的 if-else 或 switch 判断。
组合技: 常与工厂模式结合使用,由工厂负责创建具体的策略对象
代码举例:
cpp
#include <iostream>
#include <memory>
// 抽象策略类:所有的收费算法都要实现这个接口
class CashStrategy {
public:
virtual ~CashStrategy() = default;
// 计算实际收费的接口
virtual double calculate(double money) = 0;
};
// 具体策略 A:正常收费
class CashNormal : public CashStrategy {
public:
double calculate(double money) override {
return money; // 原价返回
}
};
// 具体策略 B:打折扣
class CashRebate : public CashStrategy {
private:
double discount; // 折扣率,如 0.8
public:
CashRebate(double d) : discount(d) {}
double calculate(double money) override {
return money * discount;
}
};
// 具体策略 C:满减
class CashReturn : public CashStrategy {
private:
double condition; // 满足条件,如 300
double ret; // 返还金额,如 100
public:
CashReturn(double c, double r) : condition(c), ret(r) {}
double calculate(double money) override {
if (money >= condition) {
return money - ret;
}
return money;
}
};
cpp
// 上下文类:负责和具体的策略类交互
class CashContext {
private:
std::unique_ptr<CashStrategy> strategy; // 持有一个策略对象
public:
// 构造时注入具体的策略
CashContext(std::unique_ptr<CashStrategy> s) : strategy(std::move(s)) {}
// 执行计算
double getResult(double money) {
return strategy->calculate(money);
}
};
cpp
int main() {
// 场景1:正常收费
CashContext normalContext(std::make_unique<CashNormal>());
std::cout << "正常收费: " << normalContext.getResult(100) << std::endl;
// 场景2:打八折
CashContext rebateContext(std::make_unique<CashRebate>(0.8));
std::cout << "打八折: " << rebateContext.getResult(100) << std::endl;
// 场景3:满300减100
CashContext returnContext(std::make_unique<CashReturn>(300, 100));
std::cout << "满300减100: " << returnContext.getResult(400) << std::endl;
return 0;
}
5. 装饰器模式 (Decorator)
作用: 动态地给对象添加额外的职责。相比继承,它提供了一种更灵活的扩展功能的方式。
应用场景: I/O 流处理、给游戏角色动态添加装备属性、网络请求的包装(如添加日志、压缩)
代码举例:
cpp
#include <iostream>
#include <memory>
// 组件接口
class Coffee {
public:
virtual ~Coffee() = default;
virtual double cost() = 0;
virtual std::string getDescription() = 0;
};
// 具体组件:基础咖啡
class SimpleCoffee : public Coffee {
public:
double cost() override { return 2.0; }
std::string getDescription() override { return "普通咖啡"; }
};
// 装饰器基类 (也是 Coffee 的子类)
class CoffeeDecorator : public Coffee {
protected:
std::unique_ptr<Coffee> decoratedCoffee;
public:
CoffeeDecorator(std::unique_ptr<Coffee> coffee)
: decoratedCoffee(std::move(coffee)) {}
};
// 具体装饰器:加牛奶
class MilkDecorator : public CoffeeDecorator {
public:
MilkDecorator(std::unique_ptr<Coffee> coffee)
: CoffeeDecorator(std::move(coffee)) {}
double cost() override {
return decoratedCoffee->cost() + 0.5; // 基础价格 + 0.5
}
std::string getDescription() override {
return decoratedCoffee->getDescription() + " + 牛奶";
}
};
// 具体装饰器:加糖
class SugarDecorator : public CoffeeDecorator {
public:
SugarDecorator(std::unique_ptr<Coffee> coffee)
: CoffeeDecorator(std::move(coffee)) {}
double cost() override {
return decoratedCoffee->cost() + 0.2;
}
std::string getDescription() override {
return decoratedCoffee->getDescription() + " + 糖";
}
};
// --- 使用示例 ---
int main() {
// 点一杯加牛奶和糖的咖啡
auto myCoffee = std::make_unique<MilkDecorator>(
std::make_unique<SugarDecorator>(
std::make_unique<SimpleCoffee>()
)
);
std::cout << myCoffee->getDescription() << std::endl; // 普通咖啡 + 糖 + 牛奶
std::cout << "总价: $" << myCoffee->cost() << std::endl; // 2.0 + 0.2 + 0.5 = 2.7
return 0;
}