If statement 如何更换If else阻塞条件

If statement 如何更换If else阻塞条件,if-statement,design-patterns,anti-patterns,If Statement,Design Patterns,Anti Patterns,在我的代码中,我有一个if-else块条件,如下所示: public String method (Info info) { if (info.isSomeBooleanCondition) { return "someString"; } else if (info.isSomeOtherCondition) { return "someOtherString"; } else if (info.anotherCondit

在我的代码中,我有一个if-else块条件,如下所示:

public String method (Info info) {
    if (info.isSomeBooleanCondition) {
        return "someString";
    }
    else if (info.isSomeOtherCondition) {
        return "someOtherString";
    }
    else if (info.anotherCondition) {
        return "anotherStringAgain";
    }
    else if (lastCondition) {
        return "string ...";
    }
    else return "lastButNotLeastString";
}
每个条件分支返回一个字符串

既然else语句难以阅读、测试和维护,我如何替换? 我在考虑使用责任链模式,在这种情况下是否正确?
有没有其他优雅的方法可以做到这一点?

我只需简单地计算出
返回值
s:

return
    info.isSomeBooleanCondition ? "someString" :
    info.isSomeOtherCondition   ? "someOtherString" :
    info.anotherCondition       ? "anotherStringAgain" :
    lastCondition               ? "string ..." :
    "lastButNotLeastString"
;

我假设您的代码不存在于
Info
类中,因为它是在除最后一个条件之外的所有引用中传递的。我的第一反应是将
String OtherClass.method(Info)
转换为
String Info.method()
,并让它返回适当的字符串

接下来,我将看一看条件。它们是真正的条件还是可以映射到表。每当我看到代码执行查找时,比如这样,我倾向于尝试将其放入字典或映射中,以便对值执行查找

如果您有必须检查的条件,那么我将开始考虑lambda、委托或自定义接口。同一类型的一系列
if..then
可以很容易地表示出来。接下来,您将收集它们并相应地执行。依我看,这将使
if..then
bunch更加清晰。在这一点上,代码是次要的

interface IInfoCheck 
{
    bool TryCheck(Info info, out string);
}

public OtherClass()
{ 
    // Setup checks
    CheckerCollection.add(new IInfoCheck{
        public String check(out result) {
           // check code 
        }
    });
}

public String method(Info info) {    
    foreach (IInfoCheck ic in CheckerCollection) 
    {
        String result = null;
        if (ic.TryCheck(out result))
        {
            return result;
        }
   }
}

从关于这个问题的有限信息和给出的代码来看,这似乎是一个类型转换的情况。默认的解决方案是使用继承:

class Info {
public abstract String method();
};

class BooleanCondition extends Info {
    public String method() {
         return "something";
};

class SomeOther extends Info {
    public String getString() {
         return "somethingElse";
};
在本例中,有趣的模式是Decorator、Strategy和Template方法。责任链还有一个重点。链中的每个元素实现逻辑来处理一些命令。链接时,如果对象无法处理命令,则会转发该命令。这实现了一个松散耦合的结构来处理不需要集中调度的命令


如果计算条件上的字符串是一个操作,从类的名称我猜它可能是一个表达式树,您应该查看访客模式。

问题陈述不适合理想的责任链场景,因为它是看起来“被链接”但实际上“不被链接”的类型或条件。原因-一个处理责任链模式中的所有链链接,而不考虑以前的链接中发生了什么,即不跳过任何链链接(尽管您可以配置要处理的链链接和不处理的链链接-但链链接的执行仍然不取决于以前链链接的结果)。但是,在这个if-else-if*场景中,一旦if语句条件匹配,就不会计算进一步的条件

我已经想到了一种替代设计,它可以在不使用if-else的情况下实现上述功能,但它更长,但同时更灵活

假设我们有一个功能接口IfElseReplacer,它将“info”作为输入,并给出“String”输出

public Interface IfElseReplacer(){
   public String executeCondition(Info);
}
然后,可以将上述条件重新表述为lambda表达式如下所示:
“(Info Info)->Info.someCondition?someString”
“(Info)->Info.anotherCondition?someOtherString” 等等 然后我们需要一个processConditons方法来处理这些lambda-它可能是ifElseReplacer中的默认方法-

default String processConditions(List<IfElseReplacer> ifElseReplacerList, Info info){
String strToReturn="lastButNotLeastString";
for(IfElseReplacer ifElseRep:ifElseReplacerList){
    strToReturn=ifElseRep.executeCondition(info);
    if(!"lastButNotLeastString".equals(strToReturn)){
         break;//if strToReturn's value changes i.e. executeCondition returns a String valueother than "lastButNotLeastString" then exit the for loop
    }
  return strToReturn;
}
默认字符串处理条件(列出ifElseReplacerList,Info){
String strotreturn=“lastButNotLeastString”;
for(IfElseReplacer ifElseRep:ifElseReplacerList){
strToReturn=ifElseRep.executeCondition(信息);
如果(!“lastButNotLeastString.”等于(strotreturn)){
break;//如果strotreturn的值发生更改,即executeCondition返回的字符串值不是“lastButNotLeastString”,则退出for循环
}
返回strotreturn;
}
现在剩下的是(我将跳过此代码-请让我知道您是否需要它,然后再编写此代码)—— 从需要检查if-else条件的地方-

  • 创建一个lambda表达式数组,如上所述,将它们分配给IfElseReplacer接口,同时将它们添加到IfElseReplacer类型的列表中
  • 将此列表连同Info实例一起传递给默认方法processConditions()
  • 默认方法将返回字符串值,该值与问题语句中给定的if-else-if*块的结果相同

  • 我认为,上面的代码仍然是一样的:阅读、测试和维护都很困难。关键是,如果编写没有if的代码,那么编写单元测试就更容易了。因此,我想找到一种优雅的方法来删除if-else。我读过这篇文章,我认为它更好地解释了为什么避免if-else很有用:@nolanofra那篇文章没有r我发现我上面的代码片段很容易阅读和维护。我觉得如果你能使用
    switch
    语句,这会让代码更容易阅读。@melpomene我可以提供很多理由说明为什么if-else是反模式的,但我认为这不是正确的位置和正确的帖子。下面的问题是:在我的代码中使用责任链模式是否正确?你知道其他删除if-else的方法吗?如果知道,请回复帖子,否则不要这样做。我发现很难遵循你在评论中提到的@melponeme的答案的逻辑。它从“过度使用深度嵌套的if/else是坏的”直接到在没有真正解释这一结论的情况下,“我们永远不应该使用if/else”。您能否详细说明您发布的代码如何妨碍可读性和维护?if-else不是反模式。您的示例不难阅读或维护。嵌套的if或arrow反模式是另一个野兽。