首页 > 解决方案 > 是否存在通过/失败设计模式?

问题描述

不太确定这种模式/问题的正式术语是什么,但这是我所面临的:

我有一个有点大的手术。它可以通过也可以失败。每个通过或失败都带有成功操作的结果,或有关操作失败原因的信息。我正在努力“正确”地构建这个功能。

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 没有真正的联合类型。我必须确保有人不会不小心弄乱失败结果的传递变量,反之亦然。此外,我在联合类型上调用的每个方法都必须确定它是通过还是失败(如果分支突然必须无处不在)

最后,虽然还不是一个真正的问题,但我相信这样的模式会为每个结果的通过和失败分配空间,当我知道它只能是其中一个时(即它应该占用等于 的空间Max(space(Pass),space(Fail))

这些方法似乎都不完美。我觉得应该有一种模式来解决这类问题。在那儿?

标签: javadesign-patterns

解决方案


在这种情况下,抛出错误的方法似乎是最好的。

原因

  1. 您可以为多种类型创建多个自定义异常,并在发生任何错误时。通过这种方法,您可以确保无论何时发生坏事,您的程序都会返回带有指定错误的控件。

  2. 作为返回类型,您可以返回具有特定值的结果。因此,每当您的程序返回某些内容时,它似乎可以正常工作或通过。


推荐阅读