C++中的SOLID原则:从理论到实践
SOLID原则是Robert Martin提出的面向对象设计的五项基本规则。它们有助于创建灵活、可扩展且易于维护的代码。在本文中,我们将使用C++示例逐步解析每个原则,从简单理论到实际应用场景。
1. 单一职责原则(SRP)
理论:每个类只应有一个引起变化的原因。换句话说,一个类只负责程序功能中的一个部分。
问题:开发者常常将数据逻辑、保存和屏幕输出放在同一个类中。这违反了SRP。
C++实践:让我们将Report类拆分为三个独立的类。
// 错误:违反SRPclass Report { std::string title; std::string content;public: void generate() { /* 生成报告 */ } void saveToFile(const std::string& filename) { /* 保存到文件 */ } void print() { /* 打印 */ }};
// 正确:符合SRPclass Report { std::string title; std::string content;public: void generate() { /* 仅生成报告 */ }};
class ReportSaver {public: void saveToFile(const Report& report, const std::string& filename) { /* 保存 */ }};
class ReportPrinter {public: void print(const Report& report) { /* 打印 */ }};结论:现在每个类只负责自己的任务。代码变得更容易测试和修改。
2. 开闭原则(OCP)
理论:软件实体(类、模块、函数)应对扩展开放,对修改关闭。也就是说,我们应该能够在无需更改现有代码的情况下添加新功能。
C++实践:使用多态和抽象类。
#include <iostream>#include <vector>#include <memory>
// 形状基类class Shape {public: virtual double area() const = 0; virtual ~Shape() = default;};
class Rectangle : public Shape { double width, height;public: Rectangle(double w, double h) : width(w), height(h) {} double area() const override { return width * height; }};
class Circle : public Shape { double radius;public: Circle(double r) : radius(r) {} double area() const override { return 3.14159 * radius * radius; }};
// 计算总面积类——添加新形状时无需修改class AreaCalculator {public: double totalArea(const std::vector<std::unique_ptr<Shape>>& shapes) { double total = 0; for (const auto& shape : shapes) { total += shape->area(); } return total; }};
int main() { std::vector<std::unique_ptr<Shape>> shapes; shapes.push_back(std::make_unique<Rectangle>(4, 5)); shapes.push_back(std::make_unique<Circle>(3));
AreaCalculator calc; std::cout << "总面积:" << calc.totalArea(shapes) << std::endl; return 0;}结论:我们可以在不修改AreaCalculator的情况下添加新形状(例如Triangle)。
3. 里氏替换原则(LSP)
理论:程序中的对象应该可以被其子类型的实例替换,而不会影响程序的正确性。简单来说,如果你有父类和子类,你应该能够在期望父类的地方使用子类,并且一切都能正常工作。
实践