我目前正在使用 HibernateConstraintValidator 来实现我的验证。但我的审阅者不同意在代码中使用 if/else 或!运营商。我可以使用哪种设计模式来删除验证逻辑中的 if/else?
public class SomeValidatorX implements ConstraintValidator<SomeAnnotation, UUID> {
@Autowired
SomeRepository someRepository;
@Override
public boolean isValid(UUID uuid, ConstraintValidationContext context) {
return !(uuid!=null && someRepository.existsById(uuid)); //The reviewer doesn't want this negation operator
}
}
在下面的代码中,他不需要 if/else
public class SomeValidatorY implements ConstraintValidator<SomeAnnotation, SomeClass> {
@Autowired
SomeRepository someRepository;
@Override
public boolean isValid(SomeClass someObject, ConstraintValidationContext context) {
if(someObject.getFieldA() != null) { //He doesn't want this if statement
//do some operations
List<Something> someList = someRepository.findByAAndB(someObject.getFieldA(),B);
return !someList.isEmpty(); //He doesn't want this ! operator
}
return false; // He was not fine with else statement in here as well
}
}
旁注:我们必须使用领域驱动设计(如果有帮助的话)
最佳答案
很久以前,在太初。有一项准则规定方法应该只有一个导出点。为了实现这一点,开发人员必须跟踪本地状态并使用 if/else 才能到达方法的末尾。
今天我们知道得更多了。通过尽早退出方法,在阅读代码时更容易将整个流程保留在我们的脑海中。更简单的代码意味着更少的错误。错误越少,错误就越少。
在我看来,这就是审阅者不喜欢该代码的原因。它并不像想象的那么容易阅读。
让我们看第一个例子:
public boolean isValid(UUID uuid, ConstraintValidationContext context) {
return !(uuid!=null && someRepository.existsById(uuid)); //The reviewer doesn't want this negation operator
}
代码说的是“不是这个:(uuid 不应该为空并且必须存在)”。是不是很容易理解呢?我认为不是。
替代方案:“如果 uuid 不存在也没关系,但如果存在,该项目可能不存在”。
或者在代码中:
if (uuid == null) return true;
return !someRepository.existsById(uuid);
更容易阅读,对吧? (我希望我的意图是正确的;))
第二个例子
if(someObject.getFieldA() != null) { //He doesn't want this if statement
//do some operations
List<Something> someList = someRepository.findByAAndB(someObject.getFieldA(),B);
return !someList.isEmpty(); //He doesn't want this ! operator
}
return false; // He was not fine with else statement in here as well
好的。你在这里说的是:
- 如果字段 A 不为空:
- 构建一个包含 A 和 b 的列表
- 如果该列表不为空则失败,否则成功。
- 否则失败
得出这一结论的更简单方法是简单地说:
- 字段A不指定也可以
- 如果指定了字段 A,则它必须与 B 组合存在。
翻译成代码:
if (someObject.getFieldA() == null)
return true;
return !someRepository.findByAAndB(someObject.getFieldA(),B).isEmpty();
在 C# 中,我们有 Any()
,它与 isEmpty
相反,在这种情况下我更喜欢它,因为它删除了否定。
有时需要否定。在存储库中编写新方法来避免它是没有意义的。但是,如果仅使用 findByAAndB
,我会将其重命名为 ensureCombination(a,b)
,以便它可以针对有效情况返回 true。
尝试一边说话一边编写代码,这样在脑海中创建代码的图像会更容易。你不会说“我还没吃饱,我们去吃午饭吧”,是吗? ;)
关于java - 使用哪种设计模式来避免验证类中的 if/else?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64980788/