【问题标题】:Is it OK to use this pattern for value-checking?可以使用此模式进行值检查吗?
【发布时间】:2011-07-03 13:01:22
【问题描述】:

对于我的类具有类似输入检查逻辑的方法(例如,一个自定义多维数组,它有很多方法,所有这些方法都检查给定坐标是否在数组限制内),我创建了一个单独的抛出运行时异常的私有检查器,以及一个公共检查器,它只返回一个布尔值,指示变量是否可用于此类方法。示例如下:

public class Foo {



    public void doStuff(Variable v) {

        checkVariableUnsafe(v);
        ... // do stuff
    }



    private void checkVariableUnsafe(Variable v) throws InvalidVariableException {...}



    public boolean checkVariable(Variable v) {
        try {
            checkVariableUnsafe(v);
            return true;
        } catch (InvalidVariableException e) {
            return false;
        }
    }
}

可以使用它,还是有一些我看不到的缺点?这种情况下常用的模式是什么?

【问题讨论】:

  • 设计模式专门指对象级别或类范围的解决方案,并解决与对象创建、对象交互和对象通信相关的问题。它们不是功能范围解决方案。我正在重新标记您的问题。
  • 你定义的来源是什么?根据维基百科,设计模式不一定与对象有关。 en.wikipedia.org/wiki/Design_pattern_(computer_science)
  • 所有编程都包含模式,所有编程都应该包含设计。这个想法不是定义某些东西,而是将主题保持在普遍接受的概念范围内。 “设计模式”,一个模糊的术语,但对于它通常所指的上下文有一个非常清晰的概念。大多数人理解为“设计模式”的普遍接受的概念是基于对象和创建、结构和行为模式的基本类别。该维基百科文章中引用的所有主要来源 - Fowler、Martin、Gang of Four 等都在描述基于对象的系统。

标签: java exception variables validation


【解决方案1】:

对有效性预测和实际验证使用相同的代码不仅仅是一个好主意,它是唯一正确的主意。由于第一条诫命是不要重复自己!,当然您应该将该检查提取到它自己的方法中。所以这正是我通常做的。

【讨论】:

    【解决方案2】:

    通常建议避免在正常程序流程中使用异常。无需在这里讨论that issue,如果您想遵循该建议,那么您可以将实际执行检查的逻辑放入公共checkVariable 方法中,并让私有checkVariableUnsafe 方法调用checkVariable 并抛出异常如果返回 false。

    我认为您的问题中没有足够的上下文来明确评论您创建的 API 的适当性,但我看不出它本质上没有任何问题。

    【讨论】:

      【解决方案3】:

      这是一个非常好的做法。我只会使用标准的IllegalArgumentException 而不是自定义的。

      【讨论】:

      • 我的自定义异常使用自定义日志信息扩展了 IllegalArgumentException;我还发现它对于预期会发生此异常的单元测试很有用:这样它们就不会意外地出现其他不预期的 IllegalArgumentExceptions。
      【解决方案4】:

      我认为这是不必要的复杂。如果您只是检查传递给方法的传入参数,我只需在检查中编程,如果失败则抛出IllegalArgumentException,然后继续。我会反抗任何对我强加如此冗长、涉嫌模式的人。

      我更喜欢 Spring 的绑定和验证 API 之类的东西,但这不是你所拥有的。您提出的复杂性似乎对我没有任何帮助。

      【讨论】:

      • 如果调用者能够知道输入何时有效,我同意你的看法。如果只有 Foo 能够知道输入是否有效,我看不出比这个更好的解决方案。仅仅抛出一个异常将迫使调用者尝试调用该方法并捕获 IllegalArgumentException。顺便说一句,这种模式由 Josh Bloch 推广。
      • 为什么最好在设置器之前调用布尔方法,而不是调用该方法并捕获任何导致的异常?我唯一能看到这有用的是,如果您想在实际设置之前检查输入是否有效,即。如果用户的首选用户名已被使用,则向用户显示警告。
      • 正如您所描述的原因,它很有用,并且因为依赖异常进行流控制是不好的做法。正如 PMD 所说 (pmd.sourceforge.net/rules/…):使用异常作为流控制会导致 GOTOish 代码并在调试时掩盖真正的异常。这也是 J. Bloch 的建议。请参阅lcsd05.cs.tamu.edu/slides/keynote.pdf(幻灯片 38)
      • 如果您需要验证多个业务对象,使用布尔方法而不是异常会很方便;它为您购买了更具可读性和更紧凑的验证代码。
      • 杰西,就是这样。
      猜你喜欢
      • 2014-01-30
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多