【发布时间】:2017-04-05 08:40:40
【问题描述】:
考虑一个像下面这样的类
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)。
你有做这种事情的经验吗?
【问题讨论】:
-
我以前做过同样的事情,但没有链接。我这样做的方式是 1.) 创建一个接口
Checkable,其中包含一个需要抛出一些CheckFailedException的方法check(),以及该接口的一些具体实现。 2.) 在MyClass中创建一个List<Checkable>变量,MyClass中的check()遍历checkable 的每个元素并在其上调用check()。 3.)使用构造函数或setter方法初始化要执行的检查列表(我使用的是spring,所以我这样做了)。 -
是的,这可能有效。但我认为那里有更好的解决方案。目前,我仍在尝试使用 Try-Failure-Success-Pattern 来做到这一点,就像这里所做的那样:dzone.com/articles/whats-wrong-java-8-part-iv。不同之处在于:在链接中,他们是为异常做的......我正在使用这个 Try-Success-Failure-Implementations 顺便说一句:gist.github.com/mariofusco/8287951
-
如果你知道编译时的约束,你能使用 Hibernate Validator 吗? hibernate.org/validator
-
@aepure:检查不仅与数据库相关的事情有关。
-
@Chris311 我喜欢你的实现。事实上,我也可能在我的应用程序中使用它。我的想法是,您想连锁检查,对吗?你可以尝试做类似
Try<Checkable>的事情,但我担心这会造成更多的开销和混乱,或者在最坏的情况下使事情变得混乱......
标签: java refactoring chaining