《代码整洁之道》读书笔记二
动词与关键字
给函数取个好名字,能较好地解释函数的意图,以及参数的顺序和意图。
-
对于一元函数,函数和参数应当形成一种非常良好的动词/名词形式。
// good write(name) // better // 更具体,它告诉我们,"name"是一个"field" writeField(name) -
函数名称的关键字(keyword)形式。使用这种形式,把参数的名称编码成了函数名
// bad assertEqual(expected, actual); // good // 这大大减轻了记忆参数顺序的负担 assertExpectedEqualsActual(expected, actual);
函数
短小
- 函数第一条规则是要短小。第二条规则不是要短小。越短小越好,
20行封顶 if、else、while等语句,其中的代码应该只有一行。该行大抵应该是一个函数调用语句。因为块内的函数拥有较具体说明性的名称,从而增加了文档上的价值
只做一件事
确保函数不能被再拆分
参数
最理想的参数数量是零,其次是一,再次是二,应尽量避免三
- 不要传递标识参数,标识参数大声宣布函数不是做一件事。如果标识为
true将会这样,标识为false则会那样 -
二元函数:有些时候两个参数正好。例如
Point p = new Point(0, 0);因为点天生拥有两个参数。但大多数情况下应该尽量利用一些机制将二元函数转换成一元函数。例如,把writeField 方法写成outputStream的成员之一// bad writeField(outputStream, name); // good outputStream.writeFiled(name); -
参数对象:如果函数看起来需要两个、三个、或三个以上参数,就说明其中一些应该封装为类了
// bad Circle makeCircle(double x, double y, double, radius); // good Circle makeCircle(Point center, double radius);从参数封装成对象,从而减少参数数量,看起来像是在作弊,但实则并非如此。当一组参数被共同传递,就像上例中的x和y那样,往往就是该有自己名称的某个概念的一部分
无副作用
-
确保函数功能就像函数名描述的一样,不要做函数名描述以外的事情。应该为起一个更能描述函数功能的函数名
public UserValidator { private Cyptographer cyptographer; public boolean checkPassword(String userName, String password) { User user = UserGateway.findByName(userName); if(user != User.NULL) { String codePhrase = user.getPhraseEncodedByPassword(); String phrase = cyptographer.decrypt(codePhrase, password); if("Valid Password".equals(phrase)) { // 副作用在于对这个调用 // checkPassword函数,顾名思义,就是用来检查密码。该名称并未暗示它会 // 初始化该次会话。可以重命名为 checkPasswordAndIntializeSession Session.initialize(); return true; } } return false; } } -
普通而言,应该避免使用输出参数,如果函数必须要修改某种状态,就修改所属对象的状态
// bad // 读者会弄不清s是输入参数还是输出参数 // 也会弄不清这函数是把s添加到什么东西后面,还是把什么东西添加到s后面 appendFooter(s); // 函数签名 public void appendFooter(StringBuffer report){} // good report.appendFooter();

浙公网安备 33010602011771号