大家好,我是码农老吴,欢迎收看架构师书房。上期,我们聊了如何简化switch语句,本期,我们看看如何简化深层嵌套的条件语句(deeply nested conditional)。
BinaryTreeNode:二分查找树节点(binary search tree node)。
package eu.sig.training.ch03.binarytree;
public class BinaryTreeNode> {
private final T value;
private BinaryTreeNode left;
private BinaryTreeNode right;
public BinaryTreeNode(T value) {
this.value = value;
}
public void insert(T value) {
if (value.compareTo(this.value) < 0) {
if (left != null) {
left.insert(value);
} else {
left = new BinaryTreeNode(value);
}
} else {
if (right != null) {
right.insert(value);
} else {
right = new BinaryTreeNode(value);
}
}
}
public BinaryTreeNode getLeft() {
return left;
}
public BinaryTreeNode getRight() {
return right;
}
public T getValue() {
return value;
}
public boolean isLeaf() {
return left == null && right == null;
}
}
package eu.sig.training.ch03.binarytree;
@SuppressWarnings("serial")
public class TreeException extends RuntimeException {
public TreeException(String msg) {
super(msg);
}
}
BinaryTreeSearch.calculateDepth():计算二分查找树的深度
点评:
以下代码calculateDepth方法,if else 有三层嵌套。
package eu.sig.training.ch03.binarytree.v1;
import eu.sig.training.ch03.binarytree.TreeException;
import eu.sig.training.ch03.binarytree.BinaryTreeNode;
public class BinaryTreeSearch {
// tag::calculateDepth[]
public static int calculateDepth(BinaryTreeNode t, int n) {
int depth = 0;
if (t.getValue() == n) {
return depth;
} else {
if (n < t.getValue()) {
BinaryTreeNode left = t.getLeft();
if (left == null) {
throw new TreeException("Value not found in tree!");
} else {
return 1 + calculateDepth(left, n);
}
} else {
BinaryTreeNode right = t.getRight();
if (right == null) {
throw new TreeException("Value not found in tree!");
} else {
return 1 + calculateDepth(right, n);
}
}
}
}
// end::calculateDepth[]
}
(Replace nested conditional with Guard clauses pattern)
Guard clauses pattern
A guard clause is a software pattern that simplifies complex functions by “failing fast”, checking for invalid inputs up front and immediately failing if any are found.
卫语句是一种通过快速失败来简化复杂代码的软件开发模式,也是我经常使用的一种编写习惯,它常常用来简化代码嵌套的层级。这种模式的一个显著特点就是对return语句的高频使用,当然还有其他方式,大家如果感兴趣,评论区请留言,我可以做个专题分享。
package eu.sig.training.ch03.binarytree.v2;
import eu.sig.training.ch03.binarytree.BinaryTreeNode;
import eu.sig.training.ch03.binarytree.TreeException;
public class BinaryTreeSearch {
// tag::calculateDepth[]
public static int calculateDepth(BinaryTreeNode t, int n) {
int depth = 0;
if (t.getValue() == n)
return depth;
if (n < t.getValue() && t.getLeft() != null)
return 1 + calculateDepth(t.getLeft(), n);
if (n > t.getValue() && t.getRight() != null)
return 1 + calculateDepth(t.getRight(), n);
throw new TreeException("Value not found in tree!");
}
// end::calculateDepth[]
}
calculateDepth方法,经过卫语句简化之后,由原来的三层嵌套,变成了一层嵌套。
这段代码其实已经很好了,美中不足的是分支点还是有些多,大家数数有几个分支点,肯定超过4个了,作者又换了另外一种方式进行优化。
package eu.sig.training.ch03.binarytree.v3;
import eu.sig.training.ch03.binarytree.BinaryTreeNode;
import eu.sig.training.ch03.binarytree.TreeException;
public class BinaryTreeSearch {
// tag::calculateDepth[]
public static int calculateDepth(BinaryTreeNode t, int n) {
int depth = 0;
if (t.getValue() == n)
return depth;
else
return traverseByValue(t, n);
}
private static int traverseByValue(BinaryTreeNode t, int n) {
BinaryTreeNode childNode = getChildNode(t, n);
if (childNode == null) {
throw new TreeException("Value not found in tree!");
} else {
return 1 + calculateDepth(childNode, n);
}
}
private static BinaryTreeNode getChildNode(
BinaryTreeNode t, int n) {
if (n < t.getValue()) {
return t.getLeft();
} else {
return t.getRight();
}
}
// end::calculateDepth[]
}
点评
上面的代码,将一个方法,提取成了三个方法。每个方法,逻辑都很简单,分支点都不超过4个,但是代码总量增加了不少。至于是否采用,大家见仁见智,根据自己的实际情况决定。
从上面大家是否可以体悟到一个事实,简化代码并等于减少代码,简化代码单元里面的代码,并不意味着减少代码的总量。
程序员和建筑工人不同,程序员为了简单,为了美观,可以输入更多的代码,因为这些不需要成本,而建筑工人,就不能这么随意了,每一块砖,每一片瓦,每一根木头,都是会增加项目成本的。所以,程序员应该感到幸福。
本期我们就聊到这里,下期,我们开始聊第三个原则,不写重复的代码(Write code once)。
极客架构师,专注架构师成长,我们下期见。
留言与评论(共有 0 条评论) “” |