个人精进系列-好的代码-命名/注释

2020-05-09  本文已影响0人  JayWu的架构笔记

为什么需要好的代码?

大部分时间用于阅读和理解代码

借鉴学习

防止破窗

破窗效应

如何防止

什么才是好的标准?

代码约少越好?

好的标准

别人理解代码所需的时间最小化

命名

命名很难

保持一致性

每个概念一个词

使用对仗词

后置限定词

统一业务语言

统一技术语言

为名字附带更多信息

public String start(long delay)

调整

若变量是一个度量(如时间、长度),带上它的单位。

public String start(long delaySecs)

用具体代替抽象

例1

// 检查服务是否可以监听某个指定的TCP端口
public void canStart(int port)
// 完成后触发
public void trigger()

调整

要具体,不能空泛

public void canListenOnPort(int port)

public void triggerAfterCompletion()

例2

processingData

调整

validateUserCredentials

例3

popRecord()

调整

要体现做什么,而不是怎么做

getLatestEmployee()

显化隐藏的计算过程

Matcher matcher = headerPattern.matcher(line);
if(matcher.find()){
    headers.put(matcher.group(1), matcher.group(2));
}

调整

命名有含义中间变量,显化隐藏的计算过程

Matcher matcher = headerPattern.matcher(line);
if(matcher.find()){
    String userId = matcher.group(1);
    String userName = matcher.group(2);
    headers.put(userId, userName);
}

名字应该有多长?

采用非常具体的描述性的名字?

public String newNavigationControllerWrappingViewControl()

只用单个单词或者单一字母的名字?

public String s2d()

名字应该恰如其分

在小的作用域可以使用短的名字
if (debug) {
    Map<String,Integer> m = new HashMap();
    lookUpNamesNumbers(m);
    System.out.println(m);
}
为作用域大的名字采用更长的名字
Map<String,Integer> userNameAgeMap = new HashMap();
// more code
public void someMethod() {
    lookUpNamesNumbers(userNameAgeMap);
}
缩略词
doc => document
str => string
丢掉没用的词
convertToInt() => toInt()

不会误解的名字

例1

假设有一个函数用于剪切段落的内容:

public String clip(String text, int length)

猜想

调整

public String truncate(String text, int maxLength)

例2

public static final int CART_TOO_BIG_LIMIT = 10;

CART_TOO_BIG_LIMIT的边界?

使用代码

    if(shoppingCart.size() >= CART_TOO_BIG_LIMIT){
      System.out.println("Too many items in cart.")
    }

购物车逻辑为最多不能超过10件商品

调整

    public static final int MAX_ITEMS_IN_CART = 10

给布尔值命名

boolean readPassword = true;

猜想

调整

boolean needPassword = true;

boolean userIsAuthenticated = true;

更多

加上像is、has、can或者should,把布尔值变得更加明确

与使用者的期望想匹配

public double getMean() { 
    // Iterate through all samples
    // and return total / samplesSize
}

调整

public double computeMean()

注释

什么不需要注释?

不要为那些从代码本身就能快速推断的事实注释

// Find the Node in the given subtree,
// with the given name, using the given depth.
Node findNodeInSubtree(Node subtree, String name, int depth);

不要给不好的名称加注释

// Releases the handle for this key. 
// This doesn't modify the actual registry.
void deleteRegistry(String key);

调整

void releaseRegistryHandle(String key);

好代码 > 坏代码 + 好注释

代码即文档

加入评论

例1

// 出乎意料的是,对于这些数据用二叉树比用哈希表快40%

// 哈希运算的代价比左/右比较大得多

例2

// 作为整体可能会丢掉几个词,这没有问题,要100%调整太难了

例3

注释也可以用来解释为什么代码写得不那么整洁:

// 这个类正在变得越来越乱

// 也许我们应该建立一个ResourceNode子类来帮助整理

为代码中的瑕疵写注释

// TODO 采用更快的算法

给常量加注释

public final static int NUM_THREADS = 8;

这一行看上去可能不需要注释,但很可能选用这个值的程序员需要知道得比这个要多。

调整

```java
// as long as it's >= 2 * num_processors, that's good enough.
public final static int NUM_THREADS = 8;
```

站在读者的角度

意料之中的提问

公布可能的陷阱

“全局观”注释

对于团队的新成员来讲,最难的事情之一就是理解“全局观”。

// 这段代码把我们的业务逻辑与数据库粘在一起。任何应用层代码都不应该直接使用它。

// 这个类看上去很复杂,但它实际上只是个奇妙的缓存。它对系统中的其他部分一无所知。

这正是那种应该包含在高级别注释中的信息。

克服“作者心理障碍”

当你对写注释犹豫不决时,

最好的办法就是直接把你心里所想写下来,

虽然这种注释可能是不成熟的:

// 哦,天啊,如果一旦这个东西在列表中有重复的话会变得很难处理的。

调整

// 小心:字段代码不会处理列表中的重复数据(因为这很难做到)

上一篇下一篇

猜你喜欢

热点阅读