如何编写函数(续)----《代码整洁之道》读书笔记

上一篇关于函数的文章写到编写函数的几个注意事项:

函数要短小。

函数只应该做一件事。

函数的参数要尽量少,避免使用输出函数。

函数要无副作用。

函数要区分指令和询问。

本篇接着写关于函数的其他知识。

避免传标识符参数给函数。标识符是指true或false。标识符参数意味着函数至少要做两件事情:true,做一件事;false,做另一件事。我的代码、其他同事的代码,用标识符做参数的函数,很常见。如果要将标识从函数中消除,那么将增加函数个数,而且,在函数中由标识符带来的if...else...结构将转移到函数之外。这似乎没有好处。

指令型函数要使用异常处理代替状态码返回。请看代码A。

if(deleteUserById(id) === ERROR_CODE){

if(deleteUserFriendById(id) === ERROR_CODE){

return true;

}else{

log(errorMsg);

}

}else{

log(errorMsg);

}

deleteUserById(id)、deleteUserFriendById(id)都是指令型函数。将上面的代码改造为代码B。

try{

deleteUserById(id);

deleteUserFriendById(id);

}catch(Exception e){

log(e);

}

代码B明显简洁了很多,但是我不明白:不同函数抛出的异常是不同的,捕捉到异常后进行处理的代码也可能是不同的。假如需要针对不同的代码,进行不同的处理,必须去了解封装在函数内部的代码才行。这违背了“开放—封闭”原则。工作至今,我只用过几次此类处理错误的方式。需要深入函数内部去了解所抛出的异常情况,是我不使用此方式的原因。但这个方式是专家提倡的,我需慢慢琢磨,直至透彻理解它的精妙。

代码B可以进一步改写为代码C。

try{

deleteUserAndFriendById(id);

}catch(Exception e){

log(e);

}

function deleteUserAndFriendById(id){

deleteUserById(id);

deleteUserFriendById(id);

}

从代码B到代码C,遵循着编写函数的又一个原则:把其他大段代码丑陋不堪的try...catch中剥离出来。至于为什么这么做,除了简洁,我想不出其他原因。

函数命名,应该使用动词或动词短语+名词的形式。例如,write(name),就是很好的函数名称。

说点题外话。今日周五,懈怠了,中午一直在看动漫,没有写作。

同事前些天推荐使用markdown写作,今天尝试了一下。我虽然没有掌握所有的markdown技巧,但稍加运用,就有不少好处:排版好看了些,尤其是代码的排版。

你可能感兴趣的:(如何编写函数(续)----《代码整洁之道》读书笔记)