函数参数最好是0参数,其次是1个参数,2个参数,3个参数,不能再长了。
根据只做一件事原则,函数就应该只做一件事,并且足够小。通常情况, 布尔值是不应该放在函数里的。这代表函数会做两件事。
举个列子writeField(name)比writeField(outputStream, name)好懂。 第二个函数其实也好懂,但是稍微要想一想。改成outputStream.writeField(name)是不是会好一些。
再次记着函数只做一件事,函数名只描述一件事,做多了会引起读代码的问题。
public boolean checkPassword(String userName, String password) {
User user = UserGateway.findByName(userName);
if (user != User.NULL) {
String codedPhrase = user.getPhraseEncodedByPassword();
String phrase = cryptographer.decrypt(codedPhrase, password);
if ("Valid Password".equals(phrase)) {
Session.initialize();
return true;
}
}
return false;
}
从上面函数的函数名来看,这个函数只是验证用户名和密码。但是它调用了Session.initalize(). 这让其他程序员很容易忽略掉。宁可改成长一点函数名checkPasswordAndInitializeSession,也会好一些。
避免输出参数public void appendFooter(StringBuffer report),显然,输入参数是一个引用,函数要在report后加一个页脚。改成report.appendFooter() 是不是让别人读得更容易一些。
把行为与检测分开
public boolean set(String attribute, String value); 这个是常见的情况,设置一个属性,有可能设置成功,有可能失败。返回设置结果。但后续程序这样调用得时候,就会出现if (set("ausername", "unclebob"))... 这样怎么去理解呢?到底是否已经设置了属性。
改为下面代码是否会好一些。
if(attributesExist("username")){
setAttribtute("ausername", "unclebob") ;
.....
}
把try,catch提炼放到函数里,整体的原函数就容易读一些。
public void delete(Page page) {
try {
deletePageAndAllReferences(page);
} catch (Exception e) {
logError(e);
}
}
Error枚举是一种不好的做法,它会照成很多类都对它有依赖。如果它改变,这依赖它的代码都需要重新编译和重新部署。这导致程序员有重用error代码的倾向以避免重新部署。使用异常替代错误码,新异常就可以从异常类派生出来,无需重新编译或重新部署。
public enum Error { OK, INVALID, NO_SUCH, LOCKED, OUT_OF_RESOURCES, WAITING_FOR_EVENT; }