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

如何拆分DDD Value Objects中的重复逻辑以符合DRY原则

值对象重复校验逻辑优化方案

方案1:提取通用抽象基类(推荐)

把相同的非空校验、空白字符校验、长度校验逻辑全部放在抽象父类中实现,仅把可变的长度阈值由子类提供,即可复用所有通用逻辑:

// 通用字符串类型值对象抽象基类
public abstract class ConstrainedStringValueObject {
    protected final String value;

    protected ConstrainedStringValueObject(String rawValue) {
        // 通用校验逻辑统一放在父类构造执行
        if (rawValue == null || rawValue.isBlank()) {
            throw new IllegalArgumentException("值不能为空或全为空白字符");
        }
        String trimmedValue = rawValue.trim();
        if (trimmedValue.length() > getMaxLength()) {
            throw new IllegalArgumentException("值长度不能超过" + getMaxLength() + "位");
        }
        this.value = trimmedValue;
    }

    // 抽象方法,由子类返回对应最大长度
    protected abstract int getMaxLength();

    public String getValue() {
        return value;
    }

    // equals、hashCode、toString方法可统一在基类基于value实现,无需子类重复实现
}

// Username子类实现
public class Username extends ConstrainedStringValueObject {
    private static final int MAX_LENGTH = 20;

    private Username(String rawValue) {
        super(rawValue);
    }

    public static Username create(String rawValue) {
        return new Username(rawValue);
    }

    @Override
    protected int getMaxLength() {
        return MAX_LENGTH;
    }
}

// QuizTitle子类实现
public class QuizTitle extends ConstrainedStringValueObject {
    private static final int MAX_LENGTH = 50;

    private QuizTitle(String rawValue) {
        super(rawValue);
    }

    public static QuizTitle create(String rawValue) {
        return new QuizTitle(rawValue);
    }

    @Override
    protected int getMaxLength() {
        return MAX_LENGTH;
    }
}

这个方案下后续新增同类字符串值对象,只需要继承基类、指定对应最大长度即可,无需重复编写校验逻辑。

方案2:封装通用校验工具类(轻量场景适用)

如果项目不希望引入继承层次,可以把通用校验逻辑封装为静态工具方法,两个值对象的工厂方法调用时传入对应最大长度即可:

// 通用校验工具类
public class StringValueValidator {
    public static String validateAndTrim(String rawValue, int maxLength) {
        if (rawValue == null || rawValue.isBlank()) {
            throw new IllegalArgumentException("值不能为空或全为空白字符");
        }
        String trimmedValue = rawValue.trim();
        if (trimmedValue.length() > maxLength) {
            throw new IllegalArgumentException("值长度不能超过" + maxLength + "位");
        }
        return trimmedValue;
    }
}

// Username工厂方法调用示例
public static Username create(String rawValue) {
    String validValue = StringValueValidator.validateAndTrim(rawValue, MAX_LENGTH);
    return new Username(validValue);
}

该方案没有继承带来的额外复杂度,适合同类值对象数量少的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 21:06:02