C++中的六边形架构:无痛编写纯净代码

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

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

开始课程

C++中的六边形架构:如何不再害怕变更并爱上测试



您是否曾经重写过数据库模块,然后发现需要修改一半的业务逻辑?或者试图对某个类进行单元测试,却发现它拖拽了三吨来自外部世界的依赖?如果是这样——欢迎加入俱乐部。幸运的是,我们有一个工具可以一劳永逸地解决这些问题:六边形架构(也称为端口与适配器架构)。



在本文中,我们将探讨如何将这一强大概念应用于C++。您将看到的不是抽象的图表,而是可以立即使用的真实代码。是的,我们将以不狂热的方式进行——既不会让遗留项目崩溃,又能让新代码保持整洁。



什么是六边形架构(以及六边形与它有何关系)?



想象一下您应用程序的核心——这是纯粹的业务逻辑,它既不了解数据库,也不了解REST API,更不了解图形界面。在这个核心周围是端口(接口),再往外是适配器(具体实现)。从视觉上看,这类似于一个六边形,因此得名。



关键思想是:依赖关系指向内部。外部世界依赖于核心,而不是相反。这使得您可以在不更改业务逻辑的情况下更换数据库、通信协议或用户界面。听起来像梦想?让我们看看如何在C++中实现它。



经典问题:紧密耦合



典型的C++代码通常看起来像这样:



class OrderService {public:    void createOrder(const OrderData& data) {        // 业务逻辑        if (data.items.empty()) throw std::runtime_error("订单为空");

// 问题来了——直接依赖数据库 Database db("localhost", 5432); db.connect(); db.saveOrder(data); db.disconnect(); // 还依赖邮件服务 EmailSender sender("smtp.example.com"); sender.sendInvoice(data); }};


这有什么问题?一切都有问题。您无法在没有真实数据库和邮件服务器的情况下测试createOrder。如果明天您决定从PostgreSQL切换到MongoDB——您将不得不重写OrderService。而如果邮件服务通过队列变为异步——业务逻辑又要再次修改。



使用六边形架构解决问题



步骤1:定义端口(接口)



端口是一个契约,它定义了核心需要从外部世界获得什么,但不定义如何实现。



// port/OrderRepository.hclass OrderRepository {public:    virtual ~OrderRepository() = default;    virtual void save(const Order& order) = 0;    virtual std::optional<Order> findById(const std::string& id) = 0;};

// port/NotificationService.hclass NotificationService {public: virtual ~NotificationService() = default; virtual void sendInvoice(const Order& order) = 0;};


请注意:这些是纯粹的抽象类。没有任何对框架、库或外部服务的依赖。只有业务实体。



步骤2:编写核心(业务逻辑)



现在,我们的服务只依赖于接口,而不是具体实现:



// core/OrderService.hclass OrderService {public:    OrderService(OrderRepository& repo, NotificationService& notifier)        : repository_(repo), notifier_(notifier) {}

void createOrder(const OrderData& data) { // 验证——纯粹的业务逻辑 if (data.items.empty()) { throw std::invalid_argument("订单不能为空"); }

Order order = Order::create(data); repository_.save(order); notifier_.sendInvoice(order); }

private: OrderRepository& repository_; NotificationServ

博客

书籍推荐