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

DDD中Java值对象Size的javax.validation验证实现疑问

解决DDD值对象中JSR-380验证的正确姿势

你不需要在Size值对象内部持有Validator实例——因为ValidatorFactory是重量级资源,应该全局复用,而非每个值对象实例都维护一份。正确的做法是在值对象的工厂方法中触发验证,确保只有符合规则的实例能被创建。

修正后的Size值对象代码

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.Positive;
import java.util.Set;

@Getter
@EqualsAndHashCode
@RequiredArgsConstructor(access = lombok.AccessLevel.PRIVATE)
public class Size {

    // 全局复用的Validator实例,静态初始化一次
    private static final Validator VALIDATOR;

    static {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        VALIDATOR = factory.getValidator();
    }

    @Positive(message = "Size must be greater than zero")
    private final long bytes;

    public static Size ofBytes(long bytes) {
        Size size = new Size(bytes);
        validate(size);
        return size;
    }

    public static Size ofKilobytes(long kilobytes) {
        long bytes = kilobytes * 1024;
        Size size = new Size(bytes);
        validate(size);
        return size;
    }

    public static Size ofMegabytes(long megabytes) {
        long bytes = megabytes * 1024 * 1024;
        Size size = new Size(bytes);
        validate(size);
        return size;
    }

    // 封装验证逻辑,复用给所有工厂方法
    private static void validate(Size size) {
        Set<ConstraintViolation<Size>> violations = VALIDATOR.validate(size);
        if (!violations.isEmpty()) {
            // 将约束违反转换为业务异常抛出,确保无效实例不会流出
            throw new IllegalArgumentException(violations.iterator().next().getMessage());
        }
    }
}

关键说明

  1. 全局Validator实例:通过静态块初始化一次Validator,避免重复创建ValidatorFactory(该对象创建成本高,不适合频繁实例化)。
  2. 工厂方法内验证:所有创建Size的入口都先构建实例,再执行验证,确保只有合法的实例能被返回。
  3. 异常处理:验证不通过时抛出业务异常,阻止无效值对象进入领域层,符合DDD中值对象"不可变且始终有效"的原则。

对Document实体的影响

你的Document实体无需修改——因为Size的验证已经在创建阶段完成,当Document构建时传入的Size必然是合法的,无需在实体层重复验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:12:13