通用代码技巧
最后更新于:2022-04-02 03:10:46
[TOC]
> [参考](http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy)
## 读代码的次数要多与写代码
所有不要了强行精简,而丧失语义
## 不要做复杂的复用
共同点少于不同点,则写两个函数
error
```
void foo() {
if (getOS().equals("MacOS")) {
a();
} else {
b();
}
c();
if (getOS().equals("MacOS")) {
d();
} else {
e();
}
}
```
good
```
void fooMacOS() {
a();
c();
d();
}
//和
void fooOther() {
b();
c();
e();
}
```
## 提取相同部分
error
```
void foo() {
a();
b()
c();
if (getOS().equals("MacOS")) {
d();
} else {
e();
}
}
```
good
```
void preFoo() {
a();
b()
c();
}
void fooMacOS() {
preFoo();
d();
}
void fooOther() {
preFoo();
e();
}
```
## 何时需要注释
好的代码是不需要写逻辑注释的,只需要写业务注释
## 局部变量可简单
error
```
boolean successInDeleteFile = deleteFile("foo.txt");
if (successInDeleteFile) {
...
} else {
...
}
```
good
```
boolean success = deleteFile("foo.txt");
if (success) {
...
} else {
...
}
```
## 不要重用局部变量
error
```
String msg;
if (...) {
msg = "succeed";
log.info(msg);
} else {
msg = "failed";
log.info(msg);
}
```
good
```
if (...) {
String msg = "succeed";
log.info(msg);
} else {
String msg = "failed";
log.info(msg);
}
```
## 把复杂的逻辑提取出去,做成“帮助函数”
error
```
//code
// put elephant1 into fridge2
openDoor(fridge2);
if (elephant1.alive()) {
} else {
}
closeDoor(fridge2);
//code
```
good
```
void put(Elephant elephant, Fridge fridge) {
openDoor(fridge);
if (elephant.alive()) {
} else {
}
closeDoor(fridge);
}
//code
put(elephant1, fridge2);
//code
```
## 在合理的地方换行
error
```
if (someLongCondition1() && someLongCondition2() && someLongCondition3() &&
someLongCondition4()) {
...
}
```
good
```
if (someLongCondition1() &&
someLongCondition2() &&
someLongCondition3() &&
someLongCondition4()) {
...
}
```
## 避免使用自增减表达式
如 `(i++,++i,i–,–i)`
```
//error
foo(i++)
//good
int t = i; i += 1; foo(t);
```
```
//error
foo(++i)
//good
i += 1; foo(i);
```
自增在 一下两种可正常使用
1. `for(int i = 0; i < 5; i++)`
2. 单独写层一行 `i++`
## 不要在条件语句时,省略大括号
error
```
if (...)
action1();
```
由于花括号的存在,使得代码界限明确,让眼睛负担更小了
## 合理使用括号,不要依赖操作符
`1 + 2 * 3` ok
`2 << 7 - 2 * 3` error
`2 << (7 - 2 \* 3)`good
## 避免使用continue和break
循环语句(for,while)里面出现return是没问题的,然而如果你使用了continue或者break,就会让循环的逻辑和终止条件变得复杂,难以确保正确
1. 如果出现了continue,你往往只需要把continue的条件反向,就可以消除continue。
2. 如果出现了break,你往往可以把break的条件,合并到循环头部的终止条件里,从而去掉break。
3. 有时候你可以把break替换成return,从而去掉break。
4. 如果以上都失败了,你也许可以把循环里面复杂的部分提取出来,做成函数调用,之后continue或者break就可以去掉了。
案例1:
error
```
List goodNames = new ArrayList<>();
for (String name: names) {
if (name.contains("bad")) {
continue;
}
goodNames.add(name);
...
}
```
good
```
List goodNames = new ArrayList<>();
for (String name: names) {
if (!name.contains("bad")) {
goodNames.add(name);
...
}
}
```
案例2:
error
```
while (condition1) {
...
if (condition2) {
break;
}
}
```
good
```
while (condition1 && !condition2) {
...
}
```
案例3:
error
```
public boolean hasBadName(List names) {
boolean result = false;
for (String name: names) {
if (name.contains("bad")) {
result = true;
break;
}
}
return result;
}
```
good
```
public boolean hasBadName(List names) {
for (String name: names) {
if (name.contains("bad")) {
return true;
}
}
return false;
}
```
## 写直观的代码
error
```
if (action1() || action2() && action3()) {
...
}
```
good
```
if (!action1()) {
if (action2()) {
action3();
}
}
```
## 不漏下所有的条件
由于疏忽而漏掉的分支,全都会自动“掉下去”,最后返回意想不到的结果
error
```
if (...) {
if (...) {
...
return false;
}
} else if (...) {
...
return false;
}
return true;
```
good
```
if (...) {
if (...) {
...
return false;
} else {
return true;
}
} else if (...) {
...
return false;
} else {
return true;
}
```
## 不省略缺失值
error
```
String s = "";
if (x < 5) {
s = "ok";
}
```
good
```
String s;
if (x < 5) {
s = "ok";
} else {
s = "";
}
```
ok(如果请情况简单)
```
String s = x < 5 ? "ok" : "";
```
## 错误处理
不要漏掉任何一个可能返回错误的 error
如果foo和bar都可能产生异常A,你的代码应该尽可能写成
error
```
try {
foo();
bar();
} catch (A e) {...}
```
good
```
try {
foo();
} catch (A e) {...}
try {
bar();
} catch (A e) {...}
```
## 处理 null
当 find 返回 null 时候,需要对 null 有意义的处理
error
```
public String foo() {
String found = find();
if (found == null) {
return null;
}
}
```
good
```
public String foo() {
String found = find();
if (found == null) {
//code
}
}
```
';