2017-10-20 83 views
2

在我的代码 中有一个if/else语句,我想重构它。我已经搜索了许多类似的问题。比如this。 最好的答案是说责任链模式是一个不错的选择。但下面是我的代码的一部分。如果我使用CoR模式,我将创建超过70个Java类并创建一个ArrayList来保存这些类的实例。它将消耗更多的内存。我也了解了国家的模式,也需要创建这么多的课程。大量的if if else重构

只是想知道有没有更优雅的方式来解决它?

if (urlContent.contains(YLWFX)) { 
    urlContent = urlContent.replace(YLWFX + ":", ""); 
    if (urlContent.startsWith(TRANSMIT)) { 
    mProcess.onTransmit(activity, url); 
    } else if (urlContent.startsWith(TAKEORDER)) { 
    mProcess.onTakeOrder(activity, url); 
    } else if (urlContent.startsWith(GOODS)) { 
    if (urlContent.contains(GOODSMANAGER_MMZL)) { 
     mProcess.onEnterpriseShopManage(activity, url); 
    } else { 
     mProcess.onGoods(activity, url); 
    } 
    } else if (urlContent.startsWith(SUPPLIER)) { 
    mProcess.onSupplier(activity, url); 
    } else if (urlContent.startsWith(POSTS)) { 
    mProcess.onPosts(activity, url); 

    } else if (urlContent.startsWith(TEAM)) { 

    if (urlContent.contains(TEAM_LIST)) { 
     mProcess.onTeamList(activity); 
    } else if (urlContent.contains(TEAMINDEX)) { 
     mProcess.onTeamIndex(activity, url); 
    } else if (urlContent.contains(TEAMINFO)) { 
     mProcess.onTeamInfo(activity, url); 
    } else if (urlContent.contains(TEAMMEMBER_INFO)) { 
     mProcess.onTeamMemberInfo(activity, url); 
    } else { 
     mProcess.onTeam(activity, url); 
    } 
    } 
} 
+0

您可以使用单个模式匹配操作确定前导“关键字”。这可以用作检索BiConsumer的关键,用活动和URL调用。 – laune

回答

2

的情况选择,如果你不想下井COR路径,我'd建议使用switch语句。这将有助于使您的代码更具可读性,同时不会改变逻辑。所以它看起来是这样的:(这只是伪明显)

if(contains){ 
    //you will need to look at how to add this to a switch properly, 
    //just giving you an idea of how I'd look at it. 
    switch(urlContent.startswith) { 
     case TRANSMIT: 
      mProcess.onTransmit(activity, url); 
     case TAKEORDER: 
      mProcess.onTakeOrder(activity, url); 
     case GOODS: 
      if (urlContent.contains(GOODSMANAGER_MMZL)) { 
       mProcess.onEnterpriseShopManage(activity, url); 
      } else { 
       mProcess.onGoods(activity, url); 
      } 
     case SUPPLIER: 
      mProcess.onSupplier(activity, url); 
     case POSTS: 
      mProcess.onPosts(activity, url); 
     case TEAM: 
      if (urlContent.contains(TEAM_LIST)) { 
       mProcess.onTeamList(activity); 
      } else if (urlContent.contains(TEAMINDEX)) { 
       mProcess.onTeamIndex(activity, url); 
      } else if (urlContent.contains(TEAMINFO)) { 
       mProcess.onTeamInfo(activity, url); 
      } else if (urlContent.contains(TEAMMEMBER_INFO)) { 
       mProcess.onTeamMemberInfo(activity, url); 
      } else { 
       mProcess.onTeam(activity, url); 
      } 
    } 
} 

你甚至可以做另外一个交换机上的第二批别人的,如果仍然存在,但我会离开,作为一个锻炼; Tibial;)这里的一些读也:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

希望这有助于让你开始。让我知道事情的后续!

+0

并且最好在TEAM的情况下添加新方法 – chokdee

+0

可能。稍微想一想,最好保留TEAM情况,就好像在一个单独的方法中试图打开一个.contains的语句是奇怪的一样。在我看来,只要他能够提取他的urlContent的第一个词(这不应该太复杂),我认为上面应该工作。我想这也取决于他正在比较的urlContent的格式。 –

+0

可能是我对设计模式的想法太多了。它似乎是最佳实践 –

1

你应该尽量考虑型动物像开关结构

switch (/*Variable*/) 
{ 
    case /*Argument*/: 
    /*Action*/; 
    break;   
    default: 
    /*Action*/;    
} 

或三元操作

int result = testCondition ? value1 : value2 
+0

我不认为这种方法会有帮助,因为他没有检查单个变量,而是检查变量的变量子字符串。 – Bernat

0

首先,关于很多if-else的问题并不是它们有多少,而是它们有多深。请参阅here关于如何测量它,以及为什么具有高深度嵌套if-else链的程序不可取。其次,if-else是命令式语言中最重要的语句,例如java。因此,把它们放在一个单独的方法中,或者像CoR那样将它们分散到类层次结构中,这只是程序范例的自然使用方式。

那么,有人可以这样说:“但这种代码可能有点问题,有很多if-else”。在这种情况下,我猜这个问题本身并不是if-else的大量使用,但是,也许这个方法有很多横切责任。有设计模式称为“抓取设计模式”,其中一人更普遍的名单说:

“高内聚是试图保持对象 适当集中,便于管理和可理解的评价模式。”

在关键的book of Craig Larman中可以找到更多关于抓取设计图案的信息。因此,如果一个方法内的代码有很多不同的事情要做(格式化,重写,路由,验证等),那么他们就没有其他方式将它编码为嵌套或不嵌套的胖序列 - 说明。在这种情况下,解决方案就是将这个方法分解成其他方法的有限集合,在同一个类中,或者如CoR模式中提出的,沿着其他几个类。