C++中的SOLID原则:从理论到实践,编写干净代码

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么SOLID对C++开发者很重要?

\n\n

SOLID是罗伯特·马丁(Bob大叔)提出的面向对象编程五大基本原则的首字母缩写。对于C++开发者来说,这些原则不仅仅是抽象的理论,更是帮助创建灵活、可维护和可测试应用程序的实用工具。在内存管理和性能至关重要的C++世界中,遵循SOLID原则可以避免“意大利面条式代码”,并简化重构过程。

\n\n

在本文中,我们将通过具体的C++示例逐一解析每个SOLID原则。您将看到违反原则如何导致问题,以及如何修复这些问题。我们将使用现代C++(C++11/14/17/20),以确保示例具有时效性。

\n\n

1. 单一职责原则(SRP)

\n\n

原则核心

\n

一个类应该只有一个引起变化的原因。换句话说,每个类只负责系统的一个功能或一个方面。

\n\n

C++中违反SRP的示例

\n

考虑一个违反SRP的类:它同时管理报告数据和报告格式。

\n\n
class Report {\npublic:\n    void generateReport(const std::vector<Data>& data) {\n        // 数据处理逻辑\n        m_data = data;\n    }\n    \n    void saveToFile(const std::string& filename) {\n        // 保存到文件的逻辑\n        std::ofstream file(filename);\n        for (const auto& item : m_data) {\n            file << item.toString() << "\\n";\n        }\n    }\n    \n    void printToConsole() {\n        // 输出到控制台的逻辑\n        for (const auto& item : m_data) {\n            std::cout << item.toString() << std::endl;\n        }\n    }\n    \nprivate:\n    std::vector<Data> m_data;\n};
\n\n

问题:如果输出格式发生变化,就必须修改Report类。如果数据存储方式发生变化,同样需要修改。这违反了SRP。

\n\n

修复:分离职责

\n\n
// 仅负责报告数据\nclass ReportData {\npublic:\n    void addData(const Data& item) {\n        m_data.push_back(item);\n    }\n    \n    const std::vector<Data>& getData() const {\n        return m_data;\n    }\n    \nprivate:\n    std::vector<Data> m_data;\n};\n\n// 仅负责保存\nclass FileSaver {\npublic:\n    void save(const std::string& filename, const ReportData& report) {\n        std::ofstream file(filename);\n        for (const auto& item : report.getData()) {\n            file << item.toString() << "\\n";\n        }\n    }\n};\n\n// 仅负责控制台输出\nclass ConsolePrinter {\npublic:\n    void print(const ReportData& report) {\n        for (const auto& item : report.getData()) {\n            std::cout << item.toString() << std::endl;\n        }\n    }\n};
\n\n

现在每个类只有一个引起变化的原因,这使得代码更加灵活且易于测试。

\n\n

2. 开闭原则(OCP)

\n\n

原则核心

\n

软件实体(类、模块、函数)应该对扩展开放,对修改关闭。这意味着您应该能够添加新功能,而无需修改现有代码。

\n\n

C++中违反OCP的示例

\n

设想一个折扣计算系统,其中针对每种客户类型使用if-else语句。

\n\n
class DiscountCalculator {\npublic:\n    double calculateDiscount(const std::string& customerType, double amount) {\n        if (customerType == "regular") {\n            return amount * 0.1; // 10%\n        } else if (customerType == "vip") {\n            return amount * 0.2; // 20%\n        } else if (customerType == "premium") {\n            return amount * 0.3; // 30%\n        }\n                

博客

书籍推荐