p8架构师浅谈 Java 六边形架构

p8架构师浅谈 Java 六边形架构_第1张图片

六边形架构首先是一种设计模式,设计的初衷是解决实际问题。当应用程序与 UI、测试环境、数据库、外部 API 等依赖项进行交互时,通常会遇到一些问题。六边形架构的作用就是解耦,把核心逻辑与不需要的依赖进行隔离。

1. 什么是六边形架构

Alistair Cockburn 博士最早提出了六边形架构这个概念。他把应用程序设想为一个六边形的封闭主体,任何与核心逻辑相关的部分都位于六边形中,其余都分散在外面。通过这种方式,测试核心逻辑变得很容易,不用担心过多的外部因素。

2. 如何实现六边形架构

六边形的内外部分通过所谓的“端口(Port)和适配器(Adapter)”进行双向交互。在应用程序中,interface 作为端口。接口的实现作为适配器,通过适配器在端口之间建立通信。

3. 示例

下面举一个杂货店例子,核心业务逻辑在 `GroceryStoreService` 中。有一个用户正在使用杂货店服务,需要以下基本功能:

  • 添加商品到购物车

  • 删除指定商品

  • 查看购物车中已添加的商品

Controller 层充当适配器,通过端口(interface)适配器与应用内部通信。

```java
/**
 * Controller 层充当适配器, 与应用程序的端口进行通信
 */
@RestController
public class GroceryStoreControllerAdapter {
    // Spring 会解析 Service Bean, 由 Service Bean 处理核心业务逻辑
    @Autowired
    GroceryStoreServicePort groceryStoreService;
    @PostMapping(value = "/add/{itemId}")
    public void addItem(@RequestParam Long itemId){
        groceryStoreService.addItem(itemId);
    }
    @DeleteMapping("/delete/{itemId}")
    public void deleteItem(@RequestParam Long itemId){
        groceryStoreService.deleteItem(itemId);
    }
    @GetMapping("/fetch/all/items")
    public void fetchAllItems(){
        groceryStoreService.fetchAllItems();
    }
}
```

接下来,定义应用程序端口 `GroceryStoreServicePort`,如下所示:

```java
/**
 * 此接口作为应用程序端口
 */
public interface GroceryStoreServicePort {
    // 端口: 根据指定 id 添加商品
    void addItem(Long itemId);
    // 端口: 根据指定 id 删除商品
    void deleteItem(Long itemId);
    // 端口: 获取所有已添加的商品
    void fetchAllItems();
}
```

上面代码中用 `Adapter` 进行命名,可以推测采用了 interface 方式与应用进行通信。可以更进一步为端口提供实现层,处理整个应用的业务逻辑。下面通过 `GroceryStoreServicePortImpl` 作为示例实现。

```java
/**
 * 核心业务逻辑实现
 */
public class GroceryStoreServicePortAdapter implements GroceryStoreServicePort {
    /**
     * Spring 对 repo 进行解析, 作为数据库通信的端口
     */
    @Autowired
    GroceryStoreRepositoryPort groceryStoreRepositoryPort;
    @Override
    public void addItem(Long itemId) {
        GroceryCart groceryCart = new GroceryCart();
        // 使用标准协议,比如构造函数、setter 等设置值
        // 使用 repo 端口把实例持久化到数据库
        groceryStoreRepositoryPort.save(groceryCart);
    }
    @Override
    public void deleteItem(Long itemId)
    {
        Optional groceryCartInstance = groceryStoreRepositoryPort.findById(itemId);
        // helper 代码
        groceryStoreRepositoryPort.delete(cart);
    }
    @Override public void fetchAllItems()
    {
        // 使用 repo 端口从数据库获取所有商品
        Iterable groceryList = groceryStoreRepositoryPort.findAll();
        // 迭代获取所有商品 {...}
    }
}
```

最后在应用程序中提供 repository 层,以便能够与数据库进行通信。通过另一个端口 `GroceryStoreRepositoryPort` 实现:

```java
import entities.GroceryCart;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface GroceryStoreRepositoryPort extends CrudRepository {}
```

4. 结论

Java 六边形架构提供一种有效的解耦方法,通过“端口-适配器”的形式把核心逻辑与其他依赖进行了简单高效地隔离。最后为大家整理一些Java相关的资料,面试题附带答案【阿里。腾讯,京东等大厂】需要的可以加vx 备注【面试题】

p8架构师浅谈 Java 六边形架构_第2张图片

 

你可能感兴趣的:(程序员,Java,编程,eclipse,java,tomcat,jar,hibernate)