目前,我尝试用OO原则设计一些东西。所以,让我们说,在处理用户输入之前,我需要对其进行验证。根据OO,单独的Validator类将是正确的方法。这看起来如下:
public class Validator{
public void validate(String input) throws ValidationException{
if (input.equals("")) throw new ValidationException("Input was empty");
}
}
然后,我的处理类在通过依赖注入之前得到验证器对象将调用validator.validate(input)
关于这种设计的一个好处是,
然而,我的疑问是在Validator的设计中。根据OO,它错过了某种状态。使用此设计,它是util类,验证方法可以是static
。我读了很多次(静态)Util类是糟糕的OO设计。那么,如何在保持我提到的两个优势的同时用更多的OO来完成这项工作呢?
答案 0 :(得分:1)
示例中的验证器没有状态(并且不需要任何状态),但是另一个验证器可能需要一个(比如格式化):
示例:
public class RegExValidator {
private Pattern pattern;
public RegExValidator(String re) {
pattern = Pattern.compile(re);
}
public void validate(String input) throws ValidationException {
if (!pattern.matcher(input).matches()) {
throw new ValidationException("Invalid syntax [" + input + "]");
}
}
}
答案 1 :(得分:1)
专注于问题的OOP方面(而不是问题,如果异常是处理验证的正确方法):
为什么要有一个验证器?
interface Validator<T> {
void validate(T toValidate) throws ValidationException;
}
将使您能够编写可以验证任何类T
并且非常可测试的类。您的验证器将如下所示:
class EmptyStringValidator implements Validator<String> {
public void validate(String toValidate) {
if(toValidate == null || toValidate.isEmpty()) throw new ValidationException("empty!!!");
}
}
你可以很容易地测试它。 实际上,如果您使用的是Java 8,那么这将是一个功能接口,因此单个实用程序类可以托管多个验证器:
class ValidationUtil {
public static void emptyString(String val) // same code as above
}
和ValidationUtil::emptyString
将实施Validator<String>
。
您可以将多个验证器与复合模式组合在一起。
如果你需要的话,你也可以有一个带状态的验证器......
class ListIsSortedValidator implements Validator<Integer> {
private int lastInt = Integer.MIN_VALUE;
public void validate(Integer val) throw ValidationException {
if (val < lastInt) throw new ValidationException("not sorted");
lastInt = val;
}
}
您可以使用它来验证列表:
List<Integer> list = createList();
Validator<Integer> validator = new ListIsSortedValidator();
list.forEach(validator::validate);
答案 2 :(得分:-1)
当然,这取决于具体情况,但我认为你的直觉是正确的。这种设计可能更加面向对象。
这不仅仅是Validator
没有状态,这是一个纯粹的机械指标,它可能不是一个正确的抽象,但名称本身告诉我们一些东西。通常Validator
(或甚至EmptyStringValidator
)不属于问题域。当你必须创造纯粹技术性的东西时,这总是一个不好的迹象(虽然有时它不是两个邪恶)。
我假设您没有编写Web框架,您正在尝试编写具有某个域的应用程序。例如,它有用户注册。然后,RegistrationForm
是问题域的一部分。用户知道关于“注册表”,您可以谈论它,他们会知道您的意思。
在这种情况下,面向对象的验证解决方案是该对象负责在“提交”自身期间验证自身。
public final class RegistrationForm extends Form {
...
@Override
public void submit() {
// Do validation here
// Set input fields to error if there are problems
// If everything ok do logic
}
}
我知道这不是Web框架通常看到甚至支持的解决方案。但它是面向对象解决方案的样子。
始终牢记的两个要点是:
Validator
(如果那不是您的应用程序的域)。