为什么没有架构的C++是一种痛苦
\n如果你曾经打开过别人的(或自己旧的)C++项目,感觉眼睛开始因为一个文件中的数千行代码而流泪,而编译变成了一场需要一杯咖啡的仪式——你并不孤单。C++给予了巨大的自由:可以混合风格、重载运算符、进行模板魔法。但没有纪律的自由会导致混乱。
\nC++中的架构模式——不是大学讲座中枯燥的理论。它们是经过验证的战斗配方,当项目从“玩具”成长为工业级时,能够拯救项目。在本文中,我们将解析C++架构模式,这些模式真正简化了生活:从MVC到Observer。是的,会有很多代码。
\n\n什么是架构模式(以及它与“普通模式”有何不同)
\n许多人混淆C++设计模式(GoF:单例、工厂、适配器)与架构模式。区别很简单:
\n- \n
- 设计模式——类或模块级别的微观解决方案(例如,如何创建对象)。 \n
- 架构模式——整个应用程序级别的宏观解决方案(组件如何通信,层如何划分)。 \n
架构决定了你的项目是否会在半年后变成“大泥球”(Big Ball of Mud)。因此,让我们看看C++中最有用的三种模式。
\n\n1. C++中的MVC(模型-视图-控制器):分而治之
\nMVC是经典。它将应用程序分为三部分:数据(Model)、显示(View)和控制逻辑(Controller)。在C++中,这对于GUI应用程序(Qt、wxWidgets)甚至控制台工具尤其重要。
\n\n它在代码中是什么样子
\n想象一个最简单的计算器。Model存储结果,View输出结果,Controller处理输入。
\n#include <iostream>\n#include <string>\n\n// Model: 对GUI一无所知\nclass CalculatorModel {\npublic:\n double add(double a, double b) {\n result_ = a + b;\n return result_;\n }\n double getResult() const { return result_; }\nprivate:\n double result_ = 0;\n};\n\n// View: 仅显示\nclass CalculatorView {\npublic:\n void showResult(double value) {\n std::cout << "结果: " << value << std::endl;\n }\n void showError(const std::string& msg) {\n std::cerr << "错误: " << msg << std::endl;\n }\n};\n\n// Controller: 连接Model和View\nclass CalculatorController {\npublic:\n CalculatorController(CalculatorModel& model, CalculatorView& view)\n : model_(model), view_(view) {}\n\n void handleAdd(double a, double b) {\n double res = model_.add(a, b);\n view_.showResult(res);\n }\nprivate:\n CalculatorModel& model_;\n CalculatorView& view_;\n};\n\nint main() {\n CalculatorModel model;\n CalculatorView view;\n CalculatorController controller(model, view);\n\n controller.handleAdd(5, 3); // 输出: 结果: 8\n return 0;\n}\n为什么这很酷? 你可以将控制台View替换为Qt小部件,而无需修改Model。或者在不启动GUI的情况下为Model添加单元测试。这是从零开始设计C++应用程序的基础。
\n\n2. Observer(观察者):当变化必须被所有人注意到时
\n想象一下:你有一个温度传感器,多个面板需要在温度变化时更新。与其每秒轮询传感器(polling),Observer自己通知订阅者。这是C++架构模式,使代码成为事件驱动的。
\n\n在C++11及更高版本中的实现
\n使用智能指针和std::function来实现灵活性。
\n#include <iostream>\n#include <vector>\n#include <memory>\n#include <functional>\n\n// 观察者接口\nclass IObserv