如何拆分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
相关产品推荐
相关产品推荐

