如何替换 If-else 块条件
How replace If-else block condition
在我的代码中,我有一个 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";
}
每个条件分支 returns 一个字符串。
if-else语句难以阅读、测试和维护,如何替换?
我正在考虑使用责任链模式,在这种情况下是否正确?
有没有其他优雅的方式可以做到这一点?
我会简单地分解出 return
s:
return
info.isSomeBooleanCondition ? "someString" :
info.isSomeOtherCondition ? "someOtherString" :
info.anotherCondition ? "anotherStringAgain" :
lastCondition ? "string ..." :
"lastButNotLeastString"
;
我只能假设您的代码不存在于 Info
class 中,因为它是在除最后一个条件之外的所有引用中传递的。我的第一直觉是将 String OtherClass.method(Info)
变成 String Info.method()
并使其 return 成为合适的字符串。
接下来我要看一下条件。它们是真正的条件还是可以映射到 table。每当我看到执行查找的代码时,例如这样,我倾向于尝试将其放入字典或映射中,以便我可以执行查找值。
如果您遇到必须检查的条件,那么我会开始考虑 lambda、委托或自定义接口。可以轻松表示同一类型的一系列 if..then
。接下来,您将收集它们并相应地执行。 IMO,这将使 if..then
组更加清晰。在这一点上更多的代码是次要的。
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";
};
在这种情况下有趣的模式是装饰器、策略和模板方法。责任链还有另一个重点。链中的每个元素都实现逻辑来处理一些命令。链接时,如果对象无法处理命令,则它会转发该命令。这实现了一个松散耦合的结构来处理不需要中央调度的命令。
如果根据条件计算字符串是一个操作,并且class从名称我猜它可能是一个表达式树,你应该看看访问者模式。
问题陈述不符合理想的责任链场景,因为它是 either/or 种类或条件,看起来 'chained' 但实际上是 'not'。原因 - 处理责任链模式中的所有链-links,而不管之前的 links 中发生了什么,即没有链-links 被跳过(尽管你可以配置哪个链 link 要处理,哪个不处理 - 但链的执行仍然 - link 不依赖于前一个链 - link 的结果)。但是,在这种 if-else-if* 场景中 - 一旦 if 语句条件匹配,就不会评估进一步的条件。
我想到了一个不用if-else就可以实现上述功能的替代设计,但它更长但同时更灵活。
假设我们有一个 FunctionalInterface IfElseReplacer,它将 'info' 作为输入并给出 'String' 输出。
public Interface IfElseReplacer(){
public String executeCondition(Info);
}
然后可以将上述条件重新表述为 lambda 表达式,如下所示 -
“(信息信息)-> info.someCondition ?someString”
“(信息信息)-> 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;
}
现在剩下的是(我跳过了这个代码 - 如果你需要它请告诉我然后我也会写这个) -
从哪里需要检查 if-else 条件 -
- 如上所述创建一个 lambda 表达式数组,将它们分配给 IfElseReplacer 接口,同时将它们添加到 IfElseReplacer 类型的列表中。
- 将此列表连同 Info 实例一起传递给默认方法 processConditions()。
- 默认方法将 return 字符串值,我们将与问题陈述中给出的 if-else-if* 块的结果相同。
在我的代码中,我有一个 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";
}
每个条件分支 returns 一个字符串。
if-else语句难以阅读、测试和维护,如何替换? 我正在考虑使用责任链模式,在这种情况下是否正确? 有没有其他优雅的方式可以做到这一点?
我会简单地分解出 return
s:
return
info.isSomeBooleanCondition ? "someString" :
info.isSomeOtherCondition ? "someOtherString" :
info.anotherCondition ? "anotherStringAgain" :
lastCondition ? "string ..." :
"lastButNotLeastString"
;
我只能假设您的代码不存在于 Info
class 中,因为它是在除最后一个条件之外的所有引用中传递的。我的第一直觉是将 String OtherClass.method(Info)
变成 String Info.method()
并使其 return 成为合适的字符串。
接下来我要看一下条件。它们是真正的条件还是可以映射到 table。每当我看到执行查找的代码时,例如这样,我倾向于尝试将其放入字典或映射中,以便我可以执行查找值。
如果您遇到必须检查的条件,那么我会开始考虑 lambda、委托或自定义接口。可以轻松表示同一类型的一系列 if..then
。接下来,您将收集它们并相应地执行。 IMO,这将使 if..then
组更加清晰。在这一点上更多的代码是次要的。
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";
};
在这种情况下有趣的模式是装饰器、策略和模板方法。责任链还有另一个重点。链中的每个元素都实现逻辑来处理一些命令。链接时,如果对象无法处理命令,则它会转发该命令。这实现了一个松散耦合的结构来处理不需要中央调度的命令。
如果根据条件计算字符串是一个操作,并且class从名称我猜它可能是一个表达式树,你应该看看访问者模式。
问题陈述不符合理想的责任链场景,因为它是 either/or 种类或条件,看起来 'chained' 但实际上是 'not'。原因 - 处理责任链模式中的所有链-links,而不管之前的 links 中发生了什么,即没有链-links 被跳过(尽管你可以配置哪个链 link 要处理,哪个不处理 - 但链的执行仍然 - link 不依赖于前一个链 - link 的结果)。但是,在这种 if-else-if* 场景中 - 一旦 if 语句条件匹配,就不会评估进一步的条件。
我想到了一个不用if-else就可以实现上述功能的替代设计,但它更长但同时更灵活。
假设我们有一个 FunctionalInterface IfElseReplacer,它将 'info' 作为输入并给出 'String' 输出。
public Interface IfElseReplacer(){
public String executeCondition(Info);
}
然后可以将上述条件重新表述为 lambda 表达式,如下所示 -
“(信息信息)-> info.someCondition ?someString”
“(信息信息)-> 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;
}
现在剩下的是(我跳过了这个代码 - 如果你需要它请告诉我然后我也会写这个) - 从哪里需要检查 if-else 条件 -
- 如上所述创建一个 lambda 表达式数组,将它们分配给 IfElseReplacer 接口,同时将它们添加到 IfElseReplacer 类型的列表中。
- 将此列表连同 Info 实例一起传递给默认方法 processConditions()。
- 默认方法将 return 字符串值,我们将与问题陈述中给出的 if-else-if* 块的结果相同。