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

领域驱动设计(DDD):Repository能否在Domain Service中使用?

领域驱动设计场景实现方案

认知错误修正

你对「Repository不应该在域层被调用」的认知存在偏差,该结论混淆了Repository的接口定义与具体实现:

  • DDD分层规则中,Repository的业务接口契约是定义在域层的,属于领域模型的一部分,代表领域对聚合根存储、查询能力的抽象要求
  • 只有Repository的具体技术实现(如基于JPA、MongoDB的数据库操作类)需要放在基础设施层
    域层的Domain Service完全可以依赖自身定义的Repository接口,不会违反分层依赖原则。

场景标准实现方案

1. 域层定义WatchTimeRepository接口

不要定义通用CRUD方法,直接声明贴合业务语义的查询方法,属于领域契约的一部分:

// 存放于域层的Repository接口
public interface WatchTimeRepository {
    // 查询符合播放条件的前N条WatchTime
    List<WatchTime> findEligibleWatchTimes(int limit, int rankThreshold);
}

2. 域层实现Domain Service承载业务逻辑

将rank筛选的核心业务逻辑放在域服务中,依赖上面定义的Repository接口:

// 存放于域层的领域服务
public class WatchTimeAllocationService {
    private final WatchTimeRepository watchTimeRepository;

    public WatchTimeAllocationService(WatchTimeRepository watchTimeRepository) {
        this.watchTimeRepository = watchTimeRepository;
    }

    public List<WatchTime> getWatchTimeBatchForUser(int batchSize) {
        // 核心业务逻辑:计算当前rank筛选阈值
        int currentRankThreshold = calculateRankThreshold();
        // 调用Repository接口查询数据
        List<WatchTime> candidateList = watchTimeRepository.findEligibleWatchTimes(batchSize, currentRankThreshold);
        // 可补充其他业务校验,如过滤已向当前用户曝光过的任务、排除已完成播放的任务等
        return candidateList;
    }

    private int calculateRankThreshold() {
        // 你的rank算法实现,如根据平台总任务量、剩余播放缺口、用户等级等动态调整阈值
        // 纯业务逻辑,无外部依赖
    }
}

3. 基础设施层实现Repository接口

将具体的数据库查询逻辑放在基础设施层,实现域层定义的Repository接口:

// 存放于基础设施层的Repository实现
public class JpaWatchTimeRepository implements WatchTimeRepository {
    private final JpaRepository<WatchTimePO, Long> jpaRepository;

    @Override
    public List<WatchTime> findEligibleWatchTimes(int limit, int rankThreshold) {
        // 具体查询逻辑:筛选rank≥阈值、已完成播放量<最大购买播放量的记录,取前limit条
        // 将数据库PO转换为域层WatchTime实体后返回
    }
}

4. 上层调用

应用层/接口层直接调用域服务的getWatchTimeBatchForUser方法即可,无需关心内部业务逻辑与数据查询细节。

关于Value Object的补充建议

你开头提到对Value Object的创建存在困惑,当前场景中WatchTime实体的Video URL、MaxViews、CurrentViews、rank属性都可以设计为Value Object,将属性合法性校验(如Video URL必须为合法YouTube链接、播放量必须为正整数、rank取值范围校验)封装在Value Object内部,避免业务逻辑散落在应用各处。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 10:36:01