您会使用哪种模式来实现“提前终止”逻辑?

问题描述 投票:0回答:2

在我的项目中,有几次需要使用多个条件验证值。由于至少满足这些“条件”中的一个就足够了,并且每个条件都需要大量的计算能力,因此我通常会从最轻的一个到最重的一个进行尝试,直到其中任何一个成功为止。为了实现这一点,我通常使用如下所示的模式。

bool success

do {
    if (success = condition_1()) break
    if (success = condition_2()) break
    ...
} while (false)

if (!success) {
    cleanup()
} else {
    proceed()
}

重点是我想使用“break”语句,但要做到这一点,我必须添加一个虚拟的 do-while 循环,它实际上什么也不做,只是为break语句提供上下文。我怀疑这样做是否可以。有人会推荐针对这种情况的更好模式吗?

这些是我尝试过的解决方法。

  • 将条件检查分离为函数,并使用 return 语句而不是 break => 这很好,但有时我不想制作太多函数。
  • 声明一个指示成功的通用标志,如果标志设置为 false,则运行每个条件 => 这需要评估每个步骤的 if 语句,尽管它们对性能的影响很小。
algorithm design-patterns
2个回答
0
投票

您可以只使用常规 if:

if (condition_1() || condition_2()){
  cleanup()
} else {
  proceed()
}

一旦某个值返回 true,if 的计算就会停止,并且表达式的其余部分将不会被计算。换句话说,如果条件1()返回true,则条件2()将不会被调用。

免责声明:在大多数编程语言中都是如此,但我听说过至少一种语言(WinDev)在某些时候情况并非如此,所以如果您使用外来语言,请检查您的文档。


0
投票

您可以采取多种方法,其中一些可能严重依赖于语言:

  1. 创建函数集合(可能是匿名/lambda 函数)并迭代它。伪代码:

    funcs = [() -> condition1(), () -> condition2() ...]
    success = false
    for f in funcs:
       success = success || f();
       if(success):
         break;
    
    ... cleanup
    
  2. 很多语言都支持逻辑条件的短路评估,因此如果您使用的是其中之一,那么您可以只依赖短路:

    success = condition1() || condition2() || ...
    
    ... cleanup
    
  3. 对于更复杂的场景,您可以考虑实现某种风格的pipeline,即将

    condition
    变成管道的步骤,例如每个步骤接受以下步骤并决定是否需要执行它或不是。在 ASP.NET Core 中,通过请求处理中间件管道完成了类似的事情。

© www.soinside.com 2019 - 2024. All rights reserved.