Skip to content

Commit

Permalink
✏更新 整洁代码 增加 代码示例
Browse files Browse the repository at this point in the history
  • Loading branch information
0xcaffebabe committed Sep 9, 2020
1 parent 3823de3 commit ad68312
Showing 1 changed file with 240 additions and 4 deletions.
244 changes: 240 additions & 4 deletions 软件工程/编码/整洁代码.md
Expand Up @@ -18,76 +18,312 @@
避免误导:

- 避免使用与本意相悖的词

```java
Accounts accountList; // bad
List<Account> accountList; // good
```

- 谨慎使用不同之处特别小的名称

```java
var userPermissionControllService;
var userPermissionControllerService;
```

- 以及小写字母l与大写字母O与数字 1 0 相似的情况

```java
int l = 0;
int o = 1;
if (l == 0) return o = l;
```

有意义的区分:

- 避免使用数字系列命名

```java
void copy(StringBuffer s1, StringBuffer s2); // bad
void concat(StringBuffer source, StringBuffer target); // good
```

- 避免使用意义相同的名称

使用读得出来的名称
```java
class Product{}
class ProductInfo{} // 加个Info并没有说明什么
class ProductDetail{}
```

使用读得出来的名称: 方便讨论

使用可搜索的名称:

- 为常量命名 方便维护

```java
double circleArea = 3.14 * Math.pow(radius, 2); // bad

double CIRCLE_PI = 3.1415926; // good
```

- 名称长短与其作用域大小相对应

避免使用编码:
```java
private static final double CIRCLE_PI = 3.14;

void calcArea() {
final double PI = 3.14
...
}
```

避免使用编码:这些技巧在IDE智能的时代有它的用处

- 避免匈牙利标记法在变量名称携带类型

```java
int iPort = 8080; // 该变量为int类型 bad
```

- 避免前缀标记成员变量

```java
private List<Listeners> m_listeners; // bad
```

- 避免避免接口与实现携带I前缀或者Imp后缀

```java
interface IUserService{} // bad
class UserServiceImp implements UserService {} // bad
class DefaultUserService implements UserService {} // good
```

避免思维映射:传统管用i j 表示循环计数器 其他情况下要避免使用单字母

```java
for (int i=0;i<MAX;i++){...} // 遵循传统惯例
int r = calcArea(); // bad
```

类名与对象名应该是名词或者名词短语

```java
class Customer{}
Processor processor;
```

方法名应该是动词或者动词短语

```java
void getServerInfo();
```

命名时避免抖机灵

```java
threadPoll.kill(); // bad
threadPoll.shutdown(); // good
```

使用概念一致的命名:

- SELECT DELETE UPDATE INSERT

避免将同一术语用于不同概念

尽量使用技术性名称而非业务领域名称 与问题领域更近的代码 应当采用业务领域的名称
```java
// bad
void addUser();
BigDecimal addPrice(BigDecimal target);
```

尽量使用技术性名称而非业务领域名称 是在没有技术名词 与问题领域更近的代码 可以采用业务领域的名称

```java
Queue<Job> jobQueue; // 技术名词
DinnerOrder order; // 业务名词
```

如果无法通过类或者方法来给名称提供上下文 那么只能给名称添加前缀来添加上下文了

```java
class Address {
String username;
String phone;
String country;
String postCode;
}
String addressCode; // 在一个没有上下文的环境中
```

短名称够清楚就行了 不要添加不必要的上下文

```java
class ShopSystemUserService {} // bad
```

## 函数

短小:

- 块内调用的子函数具有说明性

```java
String renderJsp(){
var classCode = compileJsp();
return executeJspService(classCode);
}
```

- 不该有复杂的嵌套结构

```java
void badFunction() { // bad
if (..) {
while(){
...
for(..){..}
}
}
}
```


只做一件事:函数内部的实现充分体现函数名称

确保函数中的语句在同一抽象层级上面

```java
String renderJsp(){
var classCode = compileJsp();
return executeJspService(classCode);
}
```

使用多态取代switch语句

```java
// bad
Money calcPay(Employee e){
switch(e.type) {
case MANAGER:
return e.getPay() - 20%;
case COMMON:
return e.getPay() - 10%;
...
}
}
// good
abstract class Employee{
abstract Money getPay();
}
class CommonEmployee{
Money getPay(){...}
}
class ManagerEmployee{
Money getPay(){...}
}
```

使用描述性的名称能理性设计思路 帮助改进之

```java
var result;
var searchResult;
var movieSearchResult; // best
```

函数参数:

- 参数越多函数越难理解
- 使用标志参数(boolean)就代表函数不止做一件事

```java
public void convertAndSend(Object object){..}
public void correlationConvertAndSend(Object object, CorrelationData correlationData){..}
public void convertAndSend(String routingKey, final Object object, CorrelationData correlationData){...} // bad

exchange.send(String rotingKey,Object msg); // better
```

- 使用标志参数(boolean)就代表函数不止做一件事 应该拆分成两个函数

```java
void submitTask(Task t, boolean flag){ // 尤其flag命名并不能说明做什么 改成isSync 可能好一点
if (flag) {
sync
}else {
async
}
}
// good
void submitTaskAsync(){...}
void submitTaskSync(){...}
```

- 函数和参数应当形成一种动词/名词对形式

```java
write(PrintWriter pw, String msg); // bad
printWriter.write(msg); // good
```

副作用:避免使用输出参数(out) 需要修改状态 就将该状态作为对象的属性

```java
void removeNegative(List<Integer> list); // bad
list.removeIf(...); // good
```

分割指令与询问:函数要么做什么 要么回答什么 不能两者得兼

```java
boolean set(String k, String v){ // bad 这个函数承担了两个职责
if (exists){
return true;
}
...
return false;
}
// good
boolean exists(String k);
void set(String k,String v);
```

异常代替错误码:

- 错误处理代码就能从主路径代码分离出来

```java
// bad
if (!err){
if (!err){
...
}
}
// good
try {

} catch (Error1){

} catch (Error2){

}
```

- 主体以及错误处理代码可以抽离成函数

```java
try {
generateSearchResult();
} catch(){
logError();
sendErrorMsg();
}
```

- 错误码枚举一旦发生修改 依赖其的模块都要重新编译 使用继承异常的方式可以进行平滑扩展

别重复自己:重复可能是软件中一切邪恶的根源
Expand Down

0 comments on commit ad68312

Please sign in to comment.