不太确定这种模式/问题的正式术语,但这是我面临的问题:
我的操作有点大。它可以通过也可以通过。每次通过或失败都会带有成功操作的结果或有关操作失败原因的信息。我正在努力'正确'地构建这个功能。
class Pass{
int someGoodStuff;
double someOtherGoodStuff;
}
class Fail{
String failureMsg;
float howMuchOperationWasOffBy;
}
class Operator{
public ??? operation(){
}
}
方法1 :失败状态就像异常一样。让我们扔掉它们。这允许我包含失败信息并使返回类型只是通过。但是,这些失败状态不是编程语言错误,它们是业务逻辑失败。所以,关于这种方法,我有两件事情是错误的:一,它将业务逻辑失败与实际的Java错误(这看起来是错误的)混淆了两点,它在没有任何正当理由的情况下完成正常的执行流程。
方法2 :java中的函数喜欢返回一个对象类型,因此Pass和Fail都实现了一个接口Result,并且具有该函数的返回类型。
interface Result{...}
class Pass implements Result{...}
class Fail implements Result{...}
class Operator{
public Result operation(){...}
}
但是,函数返回的通过和失败状态完全不同。它们几乎没有重叠变量或函数。这似乎是错误的,并且让我不得不instanceof
通过所有重要信息而失败。
方法3 :某种联合对象,可以是通过也可以是失败(但不是两者)
class Result{
public Pass pass=null;
public Fail fail=null;
}
class Operator{
public Result operation(){...}
}
这样做的好处是我可以说像
这样的东西Result result=op.operation();
if (result.succeed()){
doStuffWithPass(result.getPass());
}else{
doStuffWithFail(result.getFail());
}
这基本上就是我用instanceof做的,但看起来更漂亮;代码现在看起来你可能期望它。很明显可以遵循。
但是,Java没有真正的Union类型。我必须确保有人不会意外地尝试弄乱失败结果的传递变量,反之亦然。此外,我在union类型上调用的每个方法都必须通过确定它是通过还是失败来判断(如果分支突然必须到处都是)
最后,尽管还不是真正关注的问题,我相信这样的模式为每个结果分配一个Pass和Fail的空间,当我知道它只能是其中之一时(即它应该占用一个空格)等于Max(space(Pass),space(Fail))
)
这些方法似乎都不完美。我觉得应该有一种模式来解决这类问题。有吗?
答案 0 :(得分:1)
在这种情况下,抛出错误的方法似乎是最好的。
<强>原因强>
您可以为多种类型创建多个自定义例外,并在发生任何错误时生成。通过这种方法,您可以确保每当发生错误时,程序都会返回具有指定错误的控件。
作为返回类型,您可以使用特定值返回结果。所以每当你的程序返回一些似乎工作或通过的东西。