引言:为什么在 C++ 中需要设计模式
设计模式(design patterns)是软件开发中常见问题的经过验证的解决方案。在 C++ 中,凭借其强大的类型系统、RAII 和多继承,设计模式获得了特别的灵活性。它们有助于使代码更加可读、可维护和可扩展。
在本文中,我们将介绍 GoF(Gang of Four)目录中的 4 个关键模式:Singleton、Factory Method、Observer 和 Strategy。每个模式都将通过 C++17/20 的实际代码示例进行说明。
创建型模式:Singleton(单例)
Singleton 确保一个类只有一个实例,并提供一个全局访问点。在 C++ 中,现代方法使用局部静态变量(自 C++11 起线程安全)。
示例:应用程序日志记录器
class Logger {public: // 删除拷贝和赋值 Logger(const Logger&) = delete; Logger& operator=(const Logger&) = delete;
static Logger& getInstance() { static Logger instance; // 自 C++11 起线程安全 return instance; }
void log(const std::string& message) { std::lock_guard<std::mutex> lock(m_mutex); std::cout << "[LOG] " << message << std::endl; }
private: Logger() = default; // 私有构造函数 ~Logger() = default; std::mutex m_mutex;};
// 使用int main() { Logger::getInstance().log("应用程序已启动"); Logger::getInstance().log("错误:文件未找到"); return 0;}优点: 唯一性保证、懒加载、线程安全。
缺点: 使测试复杂化(全局状态)、违反单一职责原则。
创建型模式:Factory Method(工厂方法)
Factory Method 定义了一个创建对象的接口,但允许子类决定实例化哪个类。在 C++ 中,通常通过虚函数和智能指针实现。
示例:生成不同类型的文档
// 抽象产品class Document {public: virtual void open() = 0; virtual void save() = 0; virtual ~Document() = default;};
// 具体产品class PDFDocument : public Document {public: void open() override { std::cout << "已打开 PDF"; } void save() override { std::cout << "已保存 PDF"; }};
class WordDocument : public Document {public: void open() override { std::cout << "已打开 Word"; } void save() override { std::cout << "已保存 Word"; }};
// 创建者(Creator)class Application {public: virtual std::unique_ptr<Document> createDocument() = 0; virtual ~Application() = default;
void newDocument() { auto doc = createDocument(); doc->open(); // 处理文档 }};
// 具体创建者class PDFApplication : public Application {public: std::unique_ptr<Document> createDocument() override { return std::make_unique<PDFDocument>(); }};
class WordApplication : public Application {public: std::unique_ptr<Document> createDocument() override { return std::make_unique<WordDocument>(); }};
// 使用int main() { std::unique_ptr<Application> app = std::make_unique<PDFApplication>(); app->newDocument(); // 输出:"已打开 PDF" return 0;}当预先不知道要创建的对象的精确类型时,此模式是理想的选择。
行为型模式:Observer(观察者)
博客
书籍推荐
推荐阅读