You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

六边形架构:核心与出站适配器的依赖关系存疑

六边形架构:业务逻辑调用适配器却不依赖它的原因

这两点完全不矛盾,核心是依赖倒置原则在六边形架构里的具体应用,拆解来看就清楚了:

  • 业务逻辑调用的是「抽象端口」,而非具体的适配器实现
    业务逻辑会根据自身需求定义抽象接口(比如数据持久化需要的保存用户、查询用户方法),这个接口属于架构的核心层,完全不涉及任何外部技术细节(比如MySQL、Redis、第三方API)。业务逻辑的代码里只会引用这个抽象接口,不会直接写任何和适配器相关的代码。

  • 出站适配器是抽象端口的实现者,它依赖业务逻辑的定义
    适配器是用来对接外部系统的具体实现,比如MySQL适配器、Redis适配器,它们必须遵守业务逻辑定义的抽象接口规范——也就是说,适配器要实现核心层的抽象接口,所以是适配器依赖业务逻辑的抽象,而非反过来。

  • 调用关系的本质是「依赖注入」
    运行时,通过依赖注入(DI)把具体的适配器实例传给业务逻辑组件。业务逻辑里的userRepository.save(user)看起来是在调用适配器,但实际上调用的是抽象方法,具体执行哪个适配器的逻辑,完全由外部注入的实例决定。业务逻辑本身根本不知道也不关心具体是MySQL还是Redis适配器,自然也就不依赖适配器。

举个伪代码例子更直观:

核心业务层(抽象定义)

// 业务逻辑自己定义的抽象端口,属于核心层
interface UserRepository {
    void save(User user);
}

// 业务逻辑服务,只依赖抽象端口
class UserService {
    private UserRepository repo;

    // 构造注入,依赖的是抽象,不是具体实现
    public UserService(UserRepository repo) {
        this.repo = repo;
    }

    public void createUser(User user) {
        // 先做业务校验、处理
        if (user.getAge() < 18) {
            throw new IllegalArgumentException("未成年无法注册");
        }
        // 调用抽象方法,和具体适配器无关
        repo.save(user);
    }
}

出站适配器层(具体实现)

// MySQL适配器,实现核心层的抽象接口,依赖核心层的定义
class MySQLUserRepoAdapter implements UserRepository {
    @Override
    public void save(User user) {
        // 具体的MySQL持久化逻辑
        executeSQL("INSERT INTO users(id, name) VALUES(?, ?)", user.getId(), user.getName());
    }
}

// Redis适配器,同样实现核心层的抽象接口
class RedisUserRepoAdapter implements UserRepository {
    @Override
    public void save(User user) {
        // 具体的Redis缓存逻辑
        redisClient.set("user:" + user.getId(), serialize(user));
    }
}

这样设计的好处很明显:如果后续要把持久化从MySQL换成Redis,只需要写一个新的适配器实现UserRepository,业务逻辑代码完全不需要修改——这就是六边形架构“业务逻辑不依赖外部细节”的核心优势。

内容的提问来源于stack exchange,提问作者Mandroid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 08:12:26