提高对条件语句的可读性(Improving legibility on conditional st

2019-10-18 14:49发布

我建立了我的Android设备中的HTTP服务器。

我使用的是大量的if-else语句来处理不同的充请求。

我将与其他人供以后使用来分享我的代码,我将不得不作出它清晰越好。 现在,我甚至不能看我的轻松代码。

我认为这个问题来自于一个类使用了大量if-else语句的。 例如。

if(purpose.equals("readProfile"){
     .....
}
else if(purpose.equals("writeProfile"){
     .....
}
    ....

我想他们的类别进行分类,并根据其类别排序的条件。 但不是很多legebility的提高。 然后我试着写短评盈的各条件。 但是,这变得更加混乱。

有什么可以做,以增加条件语句的可读性?

Answer 1:

作为Luiggi门多萨说,这是一个随访前一个问题 ...

如果您使用Java 7,您可以使用字符串的switch-case语句

    //month is a String
    switch (month.toLowerCase()) {
        case "january":
            monthNumber = 1;
            break;
          //partsleft out for sake of brevity ..
        default: 
            monthNumber = 0;
            break;
    }

(从Oracle Java教程摘录,上文引用的)。

重构

然而,这个巨大的if-else只是问题的一部分。 由于这似乎是随着时间而长势的结构,我建议彻底的重构,用什么在我看来,是一个策略模式 。 你应该:

制定涵盖所有用例的边界的界面:

interface MyStrategy {
  void execute(MyInputContext input, MyOutputContext output);
}

(使用MyInputContext和MyOutputContext只是一种方法空洞的方法,这仅仅是一个例子,但处理有响应的请求,这是有道理的,就像Servlet的工作原理)

重构的大if-else语句的内容到这个接口的情况下(这将是策略):

//VERY simplified...
class ReadProfileStrategy implements MyStrategy {
  void execute(MyInputContext input, MyOutputContext output) {
    //do the stuff that was in the if-else block in the "readProfile" part
  }
}

//... at the branching part:
MyInputContext input; //build this here
MyOutputContext output; //build this here

switch (purpose) {
    case "readProfile":
         // no need to always instantiate this, it should be stateless...
         new ReadProfileStrategy().execute();
         break;
    //... left out for sake of brevity
}

重构步骤2

如果做到这一点,您可以将字符串ID添加到界面,与实例本身,并摆脱的if-else或switch语句完全,你可以创造出通过IOC容器填充的地图(如),是最新的,并且完全灵活。

class ReadProfileStrategy implements MyStrategy {
  String getID() {
      return "readProfile";
  }

  void execute(MyInputContext input, MyOutputContext output) {
    //do the stuff that was in the if-else block in the "readProfile" part
  }
}

在上课的时候请求被处理

private final Map<String, MyStrategy> strategyMap; //fill the map using your favorite approach, like using Spring application context, using the getCode() to provide the key of the map

在处理逻辑:

MyStrategy strategy = strategyMap.get(purpose);
if(strategy!=null) {
    strategy.execute();
}
else {
    //handle error here
}


Answer 2:

这可能是超出了范围,但只是一个观察

尝试使用

if("readProfile".equals(purpose){}而不是

if(purpose.equals("readProfile"){}

这将有助于避免空品特例外



Answer 3:

枚举可以帮助 - 你也可以将它们添加功能。

public void test(String purpose) {
  if (purpose.equals("readProfile")) {
    // Read.
  } else if (purpose.equals("writeProfile")) {
    // Write.
  }
}

enum Purpose {
  readProfile {
    @Override
    void doIt() {
      // Read.
    }
  },
  writeProfile {
    @Override
    void doIt() {
      // Write.
    }
  };

  abstract void doIt();

}
public void test2(String purpose) {
  Purpose.valueOf(purpose).doIt();
}


Answer 4:

您可以尝试使用某种操作接口与每个块的实现,并预装了此操作的具体实现的地图。

interface Action {
    void execute();
}

Map<String, Action> actions = new HashMap<>();
actions.put("readProfile", new Action() { ... });
actions.put("writeProfile", new Action() { ... });

actionMap.get(purpose).execute();    

这会降低你的圈复杂度为好。 当然,你应该预装地图只有一次。



Answer 5:

好吧,如果这是有道理里面的if-else条件代码分离到另一个类,或者是用工厂模式。 也使所有分离类实现公共接口(例如: MyActivity.class )用方法如execute()

厂决定什么对象( ReadProfile.classWriteProfile.class等)的基础上,你把这个字符串被创建,然后调用execute()方法。

MyActivity obj = MyFactory.createMyActivity(String)
obj.execute(...);


文章来源: Improving legibility on conditional statement