闪学it-Java架构师

3 阅读4分钟

一、分层架构:经典,但容易腐化

大多数 Java 项目起步都是三层:

  • Controller:接收请求,返回响应。
  • Service:业务逻辑。
  • DAO / Repository:数据访问。

这没错,职责清晰,上手快。但问题出在依赖方向上:Controller 依赖 Service,Service 依赖 DAO,DAO 依赖数据库。业务逻辑被夹在中间,往上要迁就接口协议,往下要迁就数据库表结构。

一旦数据库换类型、接口换协议、或者想给业务逻辑写单元测试,就会发现 Service 层被框架和 SQL 绑得死死的。分层没错,错在依赖方向。


二、六边形架构:让业务独立于技术

六边形架构(也叫端口-适配器架构)的核心思想很简单:

  • 领域层:纯业务逻辑,不依赖任何框架、数据库、Web。
  • 端口(Port) :领域层定义的接口,表示“我需要什么”。
  • 适配器(Adapter) :具体实现,比如 JPA、Redis、HTTP 客户端。

依赖方向反转了:不是业务依赖数据库,而是数据库适配器去实现业务定义的接口。业务逻辑处在中心,外部技术围绕它插拔。

这样做的好处:

  • 业务逻辑可以脱离 Spring 容器独立测试。
  • 换数据库、换消息队列,只改适配器,不动业务。
  • 模块边界清晰,适合长期演进。

三、少量代码:一个六边形风格的订单服务

下面这段代码展示了六边形架构的最小骨架。领域层定义一个端口,基础设施层实现它,应用服务只依赖端口。

// 端口:领域层定义,不依赖任何框架
public interface OrderRepository {
    Order findById(String id);
    void save(Order order);
}

// 适配器:基础设施层实现,依赖 JPA
@Repository
public class JpaOrderRepository implements OrderRepository {
    private final JpaOrderDao dao;
    public JpaOrderRepository(JpaOrderDao dao) { this.dao = dao; }
    public Order findById(String id) { return dao.findById(id).orElse(null); }
    public void save(Order order) { dao.save(order); }
}

// 应用服务:只依赖端口,不依赖具体实现
@Service
public class OrderService {
    private final OrderRepository repo;
    public OrderService(OrderRepository repo) { this.repo = repo; }
    public void placeOrder(String id) {
        Order order = repo.findById(id);
        order.place();
        repo.save(order);
    }
}

注意 OrderService 只认识 OrderRepository 接口,完全不知道 JPA 的存在。测试时传入一个内存实现即可,不需要启动数据库。


四、微服务不是终点,架构是演进

很多团队从单体直接跳到微服务,结果分布式复杂度爆炸。其实六边形架构和微服务并不冲突:六边形管的是单个服务内部的边界,微服务管的是服务之间的边界。

合理的路径是:

  1. 先用六边形架构把单体内部切干净,模块之间通过端口通信。
  2. 当某个模块确实需要独立部署、独立扩展时,再把它拆成微服务。
  3. 服务之间用轻量协议(HTTP、gRPC、消息)通信,同样遵循端口-适配器思路。

架构不是一步到位,而是随着业务复杂度演进的。


五、工程化落地的四个要点

1. 依赖倒置要贯彻。
领域层不引入 Spring、JPA、MyBatis 的注解。端口定义在领域层,实现放在基础设施层。

2. 模块边界要强制。
用 Maven/Gradle 多模块,或者 ArchUnit 做架构测试。禁止 Controller 直接调 DAO,禁止领域层依赖框架。

3. 可测试性是第一指标。
如果业务逻辑必须启动 Spring 才能测,说明架构有问题。好的架构里,核心业务用纯 JUnit 就能跑。

4. 适配器要可替换。
数据库、缓存、消息队列、第三方 API,都应该藏在适配器后面。换实现时,业务代码零改动。


六、结语

Java 架构的演进,本质上是在回答同一个问题:如何让易变的技術细节,不影响稳定的业务逻辑。  分层架构迈出了第一步,六边形架构把依赖方向彻底反转。

上面那段不到 20 行的代码,没有微服务、没有中台、没有云原生,但它体现了架构最朴素也最重要的原则:业务在中心,技术在外围,依赖指向内核。  把这个原则守住,再复杂的系统也能保持清晰。