反目的:如何检查空值?

时间:2016-05-27 16:37:29

标签: oop design-patterns null

我最近听说过the anti-if campaign以及一些OOP专家在没有ifs的情况下编写代码的努力,而是使用多态。我不知道应该如何运作,我的意思是,它应该如何运作。

我已经使用过多态(没有知道反竞选活动),所以,我很好奇"坏"和"危险" ifs和我去看我的代码(Java / Swift / Objective-C)看看我最常用的地方,看起来就是这样的情况:

  1. 检查空值。这是我使用ifs的最常见情况。如果值可能为null,我必须以正确的方式管理它。要使用它,我必须检查它是否为空。我不知道如果没有ifs,多态可以如何弥补这一点。
  2. 检查正确的值。我在这里做一个例子:假设我有一个登录/注册应用程序。我想检查用户是否确实写了密码,或者它是否超过5个字符。如果没有if / switch,怎么可能呢?同样,它不是关于类型,而是关于价值。
  3. (可选)检查错误。可选,因为它与关于正确值的第2点类似。如果我在块/闭包中得到一个值或一个错误(作为params传递),如果我不能检查它是否为空或者不是,我该如何处理错误对象?
  4. 如果您对此广告系列了解更多信息,请在范围内回答。我要求这样理解他们的目的以及如何有效地完成他们所说的话。

    所以,我知道不使用ifs可能不是最聪明的想法,而只是询问是否以及如何在OOP程序中有效地完成它。

5 个答案:

答案 0 :(得分:4)

你永远不会完全摆脱if,但你可以最小化它们。

关于空值检查,否则返回空值的方法可以返回Null Object,这个对象不表示实际值,但实现了与实际值相同的行为。它的调用者只能调用Null对象上的方法,而不是检查它是否为null。方法中可能仍有if,但调用者中不需要任何内容​​。

关于正确的值检查,最好的路径是防止对象使用不正确的属性进行实例化。然后,对象的所有用户都可以确信他们不必检查对象的属性以使用它。类似地,如果对象可以具有有效或无效的属性,则可以通过提供对当前属性值执行正确操作的更高级别的方法来将其隐藏。同样,对象内部仍然有if,但调用者中不需要任何内容​​。

关于错误检查,有一些策略比返回调用者可能忘记检查的可能为空的错误值更好。一个是提出例外。另一种方法是返回一个可以保存结果或错误的类型的对象,并提供类型安全的,if - 免费的方法来在适当的时候对任一结果进行操作,比如Java的Optional或Haskell的{ {1}}。

另请注意,Maybe语句只是连接case(实际上我已经在广告系列的主页上使用if而不是switch编写了代码/ if),还有一些模式用else if代替case

答案 1 :(得分:4)

这是一个很好的问题,并且是我参加的每个OO训练营都要问的问题。首先,我们需要了解为什么ifs 很多的代码是“坏”或“危险”的代码:

  • 他们增加了代码的cyclomatic complexity,使其难以理解。
  • 他们使测试更复杂。确保您在测试方法中测试每个分支流变得越来越困难,每个条件都会使测试设置变得麻烦。
  • 它们可能表明您的代码没有被分解成足够小的方法
  • 它们可能表示您的方法未被很好地封装

然而,有一件重要的事情需要记住 - ifs不能(也不应该)完全从代码中消除。但是,我们通常可以使用多态等技术将它们抽象出来,提取小行为,并将这些行为封装到适当的类中。

现在我们知道了为什么我们应该避免ifs的一些原因,让我们解决你的问题:

  1. 检查空值:Null object pattern可帮助您消除代码中的空检查(多态FTW)。您将返回预期对象的Special Case NullObject表示,而不是返回null。这个NullObject具有与实际对象相同的接口,您可以安全地调用任何对象的方法,而不必担心抛出空指针异常。

  2. 检查值的正确性:有很多方法可以做到这一点。例如,您可以为每个验证创建单独的ValidationRule类,然后在要验证对象时将它们链接到一起。请注意,ifs仍然存在,但它们被抽象到各个ValidationRule实现中。查看Command patternChain Of Responsibility pattern了解相关信息。

答案 2 :(得分:-1)

最好使用if检查null,而不是提出异常。另外,在常见情况下,检查null有助于我们防止使用非初始化变量进行操作。

答案 3 :(得分:-1)

使用switch加上SOLID。其他思想继承自此。

答案 4 :(得分:-2)

使用if进行Null检查比提出异常更好,因为异常会比简单的if检查浪费更多内存。