上期咱们分享了关于Java中equals与hashCode的理解java
本期咱们将分享Java中if/else复杂逻辑的处理git
在github上曾看到一些issue,国外的程序员比较忌讳写else,看到了不少这样的评论
else is horrible
,那么对于逻辑很复杂的代码段,若是用太多的if/else的话,那么会致使代码的阅读难度变大,同时会增长代码的圈复杂度
,理论上,若是一个函数的圈复杂度超过8,那么这个函数就还有可优化的地方,那么如何优化这种多分支的复杂逻辑的函数呢?手册中给出了三种方法:卫语句
、策略模式
、状态模式
,经过阅读《重构:改善既有代码的设计》
发现,解决这个问题其实有不少种,下面咱们就一一道来。程序员
这种方法应该是最经常使用的方法之一,当函数过长或者分支太多的话,就能够考虑将其中的一段代码提炼成一个独立的函数。github
public void today() {
if (isBusy()) {
System.out.println("change time.");
} else if (isFree()) {
System.out.println("go to travel.");
} else {
System.out.println("stay at home to learn Alibaba Java Coding Guidelines.");
}
}
复制代码
public void today() {
if (isBusy()) {
changeTime();
} else if (isFree()) {
goToTravel();
} else {
stayAtHomeToLearn();
}
}
private void changeTime() {
System.out.println("change time.");
}
private void goToTravel() {
System.out.println("go to travel.");
}
private void stayAtHomeToLearn() {
System.out.println("stay at home to learn Alibaba Java Coding Guidelines.");
}
复制代码
用法:算法
把某个算法替换成另外一个更清晰的算法,或将函数本体替换为另外一个算法。微信
public String foundPerson(String[] people) {
for (int i = 0; i < people.length; i++) {
if (people[i].equals("Don")) {
return "Don";
}
if (people[i].equals("John")) {
return "John";
}
if (people[i].equals("Kent")) {
return "Kent";
}
}
return "";
}
复制代码
public String foundPerson(String[] people) {
List<String> candidates = Arrays.asList(new String[] { "Don", "John", "Kent" });
for (int i = 0; i < people.length; i++) {
if (candidates.contains(people[i])) {
return people[i];
}
}
return "";
}
复制代码
用法:并发
若是有复杂的条件(if-then-else)语句,从if、then、else三个段落中分别提炼出独立函数。ide
public void today() {
if (isBusy() || isNotWeekend()) {
System.out.println("change time.");
return;
} else {
System.out.println("go to travel.");
}
}
复制代码
public void today() {
if (notFree()) {
changeTime();
} else {
goToTravel();
}
}
private boolean notFree() {
return isBusy() || isNotWeekend();
}
private void changeTime() {
System.out.println("change time.");
}
private void goToTravel() {
System.out.println("go to travel.");
}
复制代码
用法:函数
若是有一系列条件测试,都获得相同结果,将这些测试合并为一个条件表达式,并将这个条件表达式提炼成为一个独立函数。测试
public void today() {
if (isWeekend()) {
System.out.println("go to travel.");
}
if (isHoliday()) {
System.out.println("go to travel.");
}
if (noWork()) {
System.out.println("go to travel.");
}
}
复制代码
public void today() {
if (isFree()) {
System.out.println("go to travel.");
}
}
private boolean isFree() {
return isWeekend() || isHoliday() || noWork();
}
复制代码
用法:
在条件表达式的每一个分支上有相同的一段代码,将这段代码搬移到条件表达式以外。
public void today() {
if (isBusy()) {
System.out.println("change time.");
sleep();
} else if (isFree()) {
System.out.println("go to travel.");
sleep();
} else {
System.out.println("stay at home to learn Alibaba Java Coding Guidelines.");
sleep();
}
}
复制代码
public void today() {
if (isBusy()) {
System.out.println("change time.");
} else if (isFree()) {
System.out.println("go to travel.");
} else {
System.out.println("stay at home to learn Alibaba Java Coding Guidelines.");
}
sleep();
}
复制代码
用法:
在一系列布尔表达式中,某个变量带有“控制标记(Flag)”的做用,以break语句或者return语句取代控制标记。
若是多个分支都属于正常行为,就应该使用if...else...的条件表达式,若是某个条件极其罕见,就应该单独检查该条件,并在该条件为真时马上从函数中返回,这样的单独检查经常被称为卫语句。
public void today() {
if (isBusy()) {
System.out.println("change time.");
} else if (isFree()) {
System.out.println("go to travel.");
} else {
System.out.println("stay at home to learn Alibaba Java Coding Guidelines.");
}
}
复制代码
public void today() {
if (isBusy()) {
System.out.println("change time.");
return;
}
if (isFree()) {
System.out.println("go to travel.");
return;
}
System.out.println("stay at home to learn Alibaba Java Coding Guidelines.");
return;
}
复制代码
用法:
合并条件表达式
条件表达式,根据对象的类型选择不一样的行为,将这个条件表达式的每一个分支放进一个子内的覆写函数中,而后将原始函数声明为抽象函数,这一项就是手册中说的策略模式以及状态模式。 正由于有了多态,因此“类型码的switch语句”以及“基于类型名称的if-then-else”语句在面向对象程序中不多出现。
某个函数既返回对象状态值,又修改了状态,创建两个不一样的函数,其中一个负责查询,另外一个负责修改。
若干函数作了相似的工做,但在函数本体中却包含了不一样的值,创建单一函数,以参数表达那些不一样的值。
public void tenPercentRaise() {
salary *= 1.1;
}
public void fivePercentRaise() {
salary *= 1.05;
}
复制代码
public void raise(double factor) {
salary *= (1 + factor);
}
复制代码
有一个函数,其中彻底取决于参数值而采起不一样行为,针对该参数的每个可能值,创建一个独立的函数。
public void setValue(String name, int value) {
if (name.equals("height")) {
height = value;
}
if (name.equals("width")) {
width = value;
}
}
复制代码
public void setHeight(int arg) {
height = arg;
}
public void setWidth(int arg) {
width = arg;
}
复制代码
用法: