考虑下面的类
public class MyClass {
private Integer myField;
private Result result;
// more global variables
public MyResult check(Integer myParameter) {
init(myParameter);
if (myField < 0) {
result.setErrorMessage("My error message");
return result;
}
// a lot more 'checks' like above where something may be written
// to the error message and the result gets returned.
}
private void init(Integer myParameter) {
result = new Result();
result.setExistsAnnouncement(/*search a certain object via crudService with myParameter*/);
// initialize other global variables including myField
}
}
问题在于check
上面的方法太长并且有很多
return
语句。我想到了一些重构,但是仍然不确定该怎么做。我在考虑类似连锁模式的东西。然后,我将实现几个检查器类,这些检查器类调用链中的下一个检查器,或者返回result
相应的errorMessage
。
但是后来我有了一个更好的主意(至少我是这样认为的):为什么表现得不像Java 8?我想用类似的Try
- Success
-
Failure
-pattern。但是我不知道如何实现这一点。我在想类似的东西:
entrancePoint.check(firstChecker)
.check(secondChecker)
.check // and so on
这个想法是:当check
失败时,它将表现为Optional.map()
并返回类似的内容Optional.EMPTY
(或在这种情况下,类似于的内容Failure
)。如果check
成功的话应该去和做下检查(返回Success
)。
您有做类似事情的经验吗?
当我们考虑验证时,通常是复合模式。它大致描述为:
如果此有效,则执行SOMETHING 。
而且,正如您所强加的那样,您希望将多个检查器链接在一起以在其区域中执行验证,因此可以实施 “责任链” 模式。
考虑一下:
您可以有一个Result
对象,该对象可以包含有关失败的消息以及简单的true / false。
您可以拥有一个Validator
Object,该对象进行所需的任何验证并返回的实例Result
。
public interface Result {
public boolean isOk();
public String getMessage();
}
// We make it genric so that we can use it to validate
// any type of Object that we want.
public interface Validator<T> {
public Result validate(T value);
}
现在,当您说要使用多个检查器来验证“ X”时,您要强加一个 验证规则 ,该 规则
只是Validator
对象的集合,而只是其Validator
自身的实例。话虽如此,您不能再使用该Result
对象来检查规则的验证结果。您将需要一个Result
可以将结果保持为的复合对象{Validator=Result}
。看起来不是像的实现HashMap<Validator, Result>
吗?是的,因为是。
现在,您可以实现Rule
和CompositeResult
:
public class Rule extends ArrayList<Validator> implements Validator {
public Rule(Validator<?> ... chain) {
addAll(Arrays.asList(chain));
}
public Object validate(Object target) {
CompositeResult result = new CompositeResult(size());
for (Validator rule : this) {
Result tempResult = rule.validate(value);
if (!tempResult.isOk())
result.put(rule, tempResult);
}
return result;
}
}
public class CompositeResult extends HashMap<Validator, Result> implements
Result {
private Integer appliedCount;
public CompositeResult(Integer appliedCount) {
this.appliedCount = appliedCount;
}
@Override
public boolean isOk() {
boolean isOk = true;
for (Result r : values()) {
isOk = r.isOk();
if (!isOk)
break;
}
return isOk;
}
@Override
public String getMessage() {
return toString();
}
public Integer failCount() {
return size();
}
public Integer passCount() {
return appliedCount - size();
}
}
就是这样!现在,要实现您的检查器:
public class Checker1 implements Validator<Integer> {
/* Implementation */
}
public class CheckerN implements Validator<Integer> {
/* Implementation */
}
现在该进行验证了:
Validator<Integer> checkingRule = new Rule(new Checker1(), new CheckerN());
CompositeResult result = checkingRule.validate(yourParameter);
if (result.isOk())
System.out.println("All validations passed");
else
System.out.println(result.getFailedCount() + " validations failed");
简单而整洁。
我在公共仓库中上传了一个示例供您试用。
问题内容: 给定一个Java“文件”对象,如何检测它是否指向符号链接? (如果有帮助/重要,我知道该文件引用的是目录,而不是文件) 问题答案: 您也可以使用isSymbolicLink(Pathpath)方法。它将更加可靠。 Java Doc“检测符号链接 ”中的类似示例。
问题内容: 我需要检查某个值是否为null。如果它不为null,则将一些变量设置为true。这里没有其他声明。这样的条件检查太多了。 有什么方法可以在不检查所有方法返回值的情况下处理此空检查? 我认为直接检查变量并忽略NullpointerException。这是一个好习惯吗? 问题答案: 不,在Java中捕获NPE而不是对您的引用进行空检查通常不是一个好习惯。 如果您愿意,可以使用这种东西: 或
问题内容: 我想在Java中实现方法链接。 我该如何实现? 还请告诉我何时使用它。 我想创建可以按如下方式使用的方法链接: 或喜欢 或喜欢 问题答案: 让你的方法返回如下: 这样,每次调用其中一个方法后,你将获得返回的同一对象,以便可以调用另一个方法。 当你要在对象上调用一系列方法时,此技术很有用:它减少了实现该方法所需的代码量,并允许你在方法链之后使用单个返回值。 减少显示对话框所需的代码量的一
问题内容: 我正在尝试用Java实现一个简单的HashTable,该哈希表使用链接表来解决冲突,这在C语言中很容易实现,但是我不知道如何在Java中实现它,因为您不能使用指针。 。 首先,我知道这些结构已经在Java中实现,我不打算使用它,只是在这里进行培训… 所以我创建了一个元素,它是一个字符串和一个指向下一个元素的指针: 当然,我的HashTable有一个Element数组来存储数据: 这是我
这是我的一个货车租赁数据库的起始代码。 如何将汽车链接到该位置。例如,CBD的位置有Wicked,Zepplin和Floyd,Penrith有Queen。因此,如果命令行参数具有“打印CBD”,那么它必须显示CBD中可用的货车。 任何帮助将不胜感激。
我需要检查一些值是否为空。如果它不为空,那么只需将某个变量设置为true。这里没有别的说法。我做了太多这样的检查。 有没有什么方法可以在不检查所有方法返回值的情况下处理这个空检查? 我想直接检查变量并忽略NullPointerException。这是一个好的做法吗?