C++解耦合
在C++中,除了回调函数,还有多种方式可以实现解耦合。以下是主要的解耦合技术:
1. 接口抽象(面向接口编程)
// 定义接口
class IDataProcessor {
public:virtual ~IDataProcessor() = default;virtual void process(const std::string& data) = 0;
};// 具体实现
class FileProcessor : public IDataProcessor {
public:void process(const std::string& data) override {std::cout << "处理文件: " << data << std::endl;}
};class NetworkProcessor : public IDataProcessor {
public:void process(const std::string& data) override {std::cout << "处理网络数据: " << data << std::endl;}
};// 使用接口,不依赖具体实现
class DataManager {
private:std::unique_ptr<IDataProcessor> processor;
public:DataManager(std::unique_ptr<IDataProcessor> proc) : processor(std::move(proc)) {}void handleData(const std::string& data) {processor->process(data);}
};
2. 观察者模式
#include <iostream>
#include <vector>
#include <memory>class IObserver {
public:virtual ~IObserver() = default;virtual void update(const std::string& message) = 0;
};class Subject {
private:std::vector<std::weak_ptr<IObserver>> observers;public:void addObserver(std::weak_ptr<IObserver> observer) {observers.push_back(observer);}void notify(const std::string& message) {for (auto it = observers.begin(); it != observers.end();) {if (auto observer = it->lock()) {observer->update(message);++it;} else {it = observers.erase(it);}}}
};class Logger : public IObserver {
public:void update(const std::string& message) override {std::cout << "日志: " << message << std::endl;}
};class Notifier : public IObserver {
public:void update(const std::string& message) override {std::cout << "通知: " << message << std::endl;}
};
3. 策略模式
#include <iostream>
#include <memory>// 策略接口
class ISortingStrategy {
public:virtual ~ISortingStrategy() = default;virtual void sort(std::vector<int>& data) = 0;
};// 具体策略
class QuickSort : public ISortingStrategy {
public:void sort(std::vector<int>& data) override {std::cout << "使用快速排序" << std::endl;// 实现快速排序}
};class MergeSort : public ISortingStrategy {
public:void sort(std::vector<int>& data) override {std::cout << "使用归并排序" << std::endl;// 实现归并排序}
};// 上下文类
class Sorter {
private:std::unique_ptr<ISortingStrategy> strategy;public:void setStrategy(std::unique_ptr<ISortingStrategy> newStrategy) {strategy = std::move(newStrategy);}void executeSort(std::vector<int>& data) {if (strategy) {strategy->sort(data);}}
};
4. 依赖注入
#include <iostream>
#include <memory>class ILogger {
public:virtual ~ILogger() = default;virtual void log(const std::string& message) = 0;
};class FileLogger : public ILogger {
public:void log(const std::string& message) override {std::cout << "文件日志: " << message << std::endl;}
};class DatabaseLogger : public ILogger {
public:void log(const std::string& message) override {std::cout << "数据库日志: " << message << std::endl;}
};class UserService {
private:std::shared_ptr<ILogger> logger;public:// 依赖通过构造函数注入UserService(std::shared_ptr<ILogger> logger) : logger(logger) {}void createUser(const std::string& username) {// 业务逻辑logger->log("创建用户: " + username);}
};
5. 事件系统
#include <iostream>
#include <unordered_map>
#include <vector>
#include <functional>class EventDispatcher {
private:std::unordered_map<std::string, std::vector<std::function<void(const std::string&)>>> listeners;public:void subscribe(const std::string& event, std::function<void(const std::string&)> listener) {listeners[event].push_back(listener);}void publish(const std::string& event, const std::string& data) {if (listeners.find(event) != listeners.end()) {for (auto& listener : listeners[event]) {listener(data);}}}
};// 使用
class OrderService {
private:EventDispatcher& dispatcher;public:OrderService(EventDispatcher& disp) : dispatcher(disp) {}void createOrder() {// 创建订单逻辑dispatcher.publish("order_created", "订单数据");}
};
6. 模板和策略模式结合
#include <iostream>
#include <vector>// 通过模板实现编译时多态
template<typename StoragePolicy>
class DataManager : private StoragePolicy {
public:void save(const std::string& key, const std::string& value) {StoragePolicy::store(key, value);}std::string load(const std::string& key) {return StoragePolicy::retrieve(key);}
};// 存储策略
class FileStorage {
public:void store(const std::string& key, const std::string& value) {std::cout << "文件存储: " << key << " = " << value << std::endl;}std::string retrieve(const std::string& key) {return "从文件读取: " + key;}
};class MemoryStorage {
public:void store(const std::string& key, const std::string& value) {std::cout << "内存存储: " << key << " = " << value << std::endl;}std::string retrieve(const std::string& key) {return "从内存读取: " + key;}
};
7. 消息队列/命令模式
#include <iostream>
#include <queue>
#include <memory>
#include <thread>
#include <chrono>class Command {
public:virtual ~Command() = default;virtual void execute() = 0;
};class PrintCommand : public Command {
private:std::string message;
public:PrintCommand(const std::string& msg) : message(msg) {}void execute() override {std::cout << "执行命令: " << message << std::endl;}
};class CommandProcessor {
private:std::queue<std::unique_ptr<Command>> commands;bool running = true;public:void addCommand(std::unique_ptr<Command> cmd) {commands.push(std::move(cmd));}void processCommands() {while (running || !commands.empty()) {if (!commands.empty()) {auto cmd = std::move(commands.front());commands.pop();cmd->execute();}std::this_thread::sleep_for(std::chrono::milliseconds(100));}}void stop() { running = false; }
};
8. 服务定位器模式
#include <iostream>
#include <unordered_map>
#include <memory>
#include <typeindex>class ServiceLocator {
private:std::unordered_map<std::type_index, std::shared_ptr<void>> services;public:template<typename T>void registerService(std::shared_ptr<T> service) {services[std::type_index(typeid(T))] = service;}template<typename T>std::shared_ptr<T> getService() {auto it = services.find(std::type_index(typeid(T)));if (it != services.end()) {return std::static_pointer_cast<T>(it->second);}return nullptr;}
};// 使用
class DatabaseService {
public:void connect() { std::cout << "数据库连接" << std::endl; }
};class LoggingService {
public:void log(const std::string& msg) { std::cout << "日志: " << msg << std::endl; }
};
解耦合的优点总结
-
可测试性:可以轻松模拟依赖进行单元测试
-
可维护性:修改一个模块不影响其他模块
-
可扩展性:容易添加新功能
-
代码复用:组件可以在不同场景重用
-
团队协作:不同团队可以并行开发不同模块
选择哪种解耦合方式取决于具体场景:
-
需要运行时多态:使用接口抽象
-
需要事件通知:使用观察者模式或事件系统
-
需要算法切换:使用策略模式
-
需要异步处理:使用消息队列
-
需要编译时优化:使用模板
