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