Hexagonal Architecture In Context Of Spring Boot

作者:禅与计算机程序设计艺术

1.简介

Hexagonal architecture是一个设计模式,旨在帮助应用程序保持良好的模块化结构、隔离变化带来的影响。它能够实现模块的独立开发、测试、部署、甚至部署到生产环境中,从而提升应用的可维护性和复用性。在本文中,我们将讨论它是什么、为什么如此流行,以及如何在Spring Boot项目中实施它。

为什么要学习Hexagonal Architecture?

首先,让我们来看一下hexagonal架构的历史和由来吧。

20世纪90年代, 和 提出了一种名为“The onion”(凉面)架构模式的概念。他们认为,如果一个系统被拆分成多个层次,并且每一层都有自己的责任范围,那么该系统将变得更容易维护、扩展和重用。

这种架构模式逐渐成为一种流行的设计模式,因为它鼓励单一职责原则(single responsibility principle),同时避免过多的耦合。

随着时间的推移,Hexagonal Architecture也越来越流行,主要原因如下:

  1. 隔离变化的影响:Hexagonal Architecture通过围绕业务领域逻辑和边界上下文进行建模,使系统中的不同部分彼此独立、互相瞄准而又互不干扰。因此,它可以帮助你减少因修改某些功能引起的问题,并增加新功能时便于维护、集成和交付。
  2. 更好的可测性:由于各个层之间具有明确的接口定义,因此你可以轻松地对其进行单元测试,从而增强应用程序的可测试性。
  3. 提高代码重用率:Hexagonal Architecture允许你创建可重用的库或组件,这些库或组件可以根据不同的应用场景进行定制和扩展。因此,你的工程师可以在其他项目中重复利用这些组件,并节省开发时间和成本。
  4. 支持多语言编程:如果你希望你的应用程序支持多种编程语言,那么Hexagonal Architecture能够提供帮助,因为它提供了一种统一的机制来调用底层功能。
  5. 在面向服务的架构(SOA)模式下实现:虽然Hexagonal Architecture最初只是用于单体架构,但是最近已经被多种面向服务的架构模式所采用。

总的来说,Hexagonal Architecture有很多优点,正如作者所说,它们帮助你构建健壮、可维护、可伸缩、可测试、灵活且易于扩展的应用程序。然而,如果您还不是十分了解Hexagonal Architecture,那么接下来我会通过一个实际例子——如何在Spring Boot项目中实施Hexagonal Architecture来阐述它的工作原理和注意事项。

Spring Boot项目中实施Hexagonal Architecture

下面我们通过一个例子来说明如何在Spring Boot项目中实施Hexagonal Architecture。

假设我们正在开发一个电商网站,其中包含许多不同的子系统,包括商品信息、订单管理、支付处理等等。这些子系统之间存在复杂的依赖关系,导致系统难以维护。为了解决这个问题,我们可以使用Hexagonal Architecture模式来实现这个目标。

下面是Hexagonal Architecture模式的六个关键元素:

  1. Inner circle (inner layer):内部圆环。它负责业务领域模型的实现,这些模型代表了核心业务逻辑。它除了负责自己的领域逻辑外,无需知道其他子系统的存在。
  2. Outer circle (outer layer): 外部圆环。它负责为整个系统提供必要的配置和环境支持。它可以实现诸如日志记录、配置管理、资源管理等功能,这些功能被其他所有子系统共享。
  3. Adapters:适配器。它负责连接内部和外部圆环之间的边界。适配器通常需要将外部子系统的API映射到内部子系统的模型上。
  4. Ports:端口。它是应用程序的入口点。它充当客户端和内部子系统之间的桥梁,使客户端能够访问内部子系统的功能。
  5. Databases:数据库。它用于存储内部子系统的数据。对于某些子系统来说,数据库可能是持久层(persistence tier)。
  6. DDD - Domain-driven design:领域驱动设计。它作为一种软件设计方法论,旨在指导设计师和开发者构建易于理解的、完整且健壮的软件。

在本例中,我们将以一个基于Spring Boot框架的电商网站为例,展示如何实施Hexagonal Architecture模式。

创建Inner Circle层

在Spring Boot项目中,我们可以通过创建不同的Maven模块来实现Inner Circle层。以下为Inner Circle层的代码示例:

package com.example.demo.domain;

public class Product {
    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    // getters and setters...
}

这个类就是电商网站的核心业务逻辑,它包含商品的名称和价格。它定义了产品实体,包含两个属性:nameprice

创建Outer Circle层

除了Inner Circle层之外,我们还需要创建一个Maven模块来实现Outer Circle层。以下为Outer Circle层的代码示例:

@SpringBootApplication
@EnableAutoConfiguration
@Import({ DataSourceConfig.class })
public class DemoApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

这个类就是我们的SpringBoot项目的启动类。它引入了一个DataSourceConfig,后者用于配置数据源,例如设置用户名密码、URL、连接池大小等。

另外,DemoApplication使用自动配置的方式来配置Spring Boot项目,而不是手动编写配置代码。

创建Adapters

Adapters是Hexagonal Architecture模式的最后一部分,它们被用来连接Inner Circle和Outer Circle之间的边界。我们需要为每个子系统创建一个Adapter,然后将其注入到Outer Circle层中。

例如,这里有一个用于商品信息的Adapter:

package com.example.demo.adapter.product;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.example.demo.domain.Product;
import com.example.demo.repository.ProductRepository;

@Component
public class ProductServiceAdapter implements ProductService {

    @Autowired
    private ProductRepository productRepository;

    // implementation of methods from interface...
}

这个类实现了ProductService接口,并使用Spring Boot的@Autowired注解注入了一个ProductRepository

类似的,我们还需要为其他的子系统创建Adapters。

创建Ports

Ports是一个重要的组成部分,它是应用程序的入口点。它充当客户端和内部子系统之间的桥梁,使客户端能够访问内部子系统的功能。

例如,我们可以在我们的项目中创建一个通用的接口:

public interface CartService {
   Cart addItemToCart(Product product);

   List<CartLine> getCartLines();
}

这个接口定义了购物车服务的接口,包含一个addItemToCart()方法用于添加商品到购物车,还有getCartLines()方法用于获取购物车中的商品列表。

我们可以通过创建一个CartServiceImpl实现这个接口,并把它注入到某个控制器中来使用这个接口:

@RestController
public class CheckoutController {

    @Autowired
    private CartService cartService;

    @PostMapping("/checkout")
    public ResponseEntity<Void> checkout() throws Exception {

        List<CartLine> lines = cartService.getCartLines();

        // processing the payment logic...

        return ResponseEntity.ok().build();
    }
}

这个控制器调用了cartService的方法,并把购物车中的商品列表返回给用户。

类似的,我们还可以创建其他的Ports,比如搜索端口、推荐端口、广告端口等等。

配置数据源

最后一步是配置数据源,这样才能访问内部子系统的数据。

在我们的例子中,我们将使用MySQL作为数据源。为此,我们需要在配置文件中添加相应的信息:

spring:
  datasource:
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC
    username: root
    password: password

这样,我们的项目就完成了Hexagonal Architecture的实施,并且它具备良好的模块化和可扩展性。

未来发展方向

Hexagonal Architecture模式是一种经典的设计模式,而且仍在不断发展中。它已经被广泛使用,而且已经成为大型软件系统的一种重要架构。随着时间的推移,Hexagonal Architecture模式将继续得到改进和发展。

另一方面,随着云原生的兴起,云计算正在改变软件架构的理念。云原生应用将以服务的方式部署在容器之上,并被调度运行在分布式环境中。随着这一趋势的发展,Hexagonal Architecture模式正在被应用到云计算架构之上。

猜你喜欢

转载自blog.csdn.net/universsky2015/article/details/133565940