1.if层次过多。
举一个很有趣的例子,假如世界上只有两种烤鸭,在北京的叫做北京烤鸭,不在北京的叫做非北京烤鸭,写烂代码的程序员思路如下:
如果烤鸭不在地球,它一定不是北京烤鸭;
如果烤鸭不在陆地,它一定不是北京烤鸭;
如果烤鸭不在亚洲,它一定不是北京烤鸭;
如果烤鸭不在中国,它一定不是北京烤鸭;
如果烤鸭不在北京,它一定不是北京烤鸭;
否则,这是北京烤鸭。
伪代码如下:
好把,如果真有哪个程序员是这样写代码的,那么我真的很想一巴掌把它拍到火星去。不要这样嵌套好吗?就算你真的是这么想,也可以这样写:
这个时候你可以发现原来前四个条件的内容都是相同的,那么可以这样写:
当你发现前面if的条件过分臃肿的时候,可以考虑反过来会不会更容易
最终变成:
可见,逻辑简化可弥补思维的不足。
这里有两个公式:
公式1:
可以转换为:
可以转换为:
如果条件太多,且实在不知道怎么合并,可以把条件单独放到一个函数:
注意,如果条件可读性强:比如sex == “man”就不要把条件放到单独函数。
2.学会使用return降低层次
如果改为:
看起来好多了。
3.学会使用函数分割代码
我是在上大学的时候学会写代码的。有一点解不开的疑惑:为什么要写函数?我把代码从头写到尾逻辑不是更加通顺吗?每个教代码的老师,总是在开始的时候给我们讲什么是变量,什么是函数,怎么用?我好想说一句:喂,我还没决定要用函数呢!
讲这部分之前,我先讲讲这个为什么要写函数,讲为什么要写函数前,我不得不提提二分查找法。
举个例子:
有十六张扑克牌按照编号从小的顺序排列,我让你找出编号排名第11的,你怎么找呢?
按照顺序一本本找,你要找11次,如果我找的是最后一张,需要找16次(当然这里我们不讨论倒着找)
使用二分查找:分成一半,前面是1-8,后面是9-16,然后再分成一半9-12和13-16,然后再分成一半9-10和11-12,然后我找到了。我找了4次。发现了吗?速度比顺序查找要快,而且我最多只需要找4次。当查找的范围越大,二分查找相对顺序查找的优势就越明显,平均速度也更快。
好了,懂了二分查找,我们再来弄清楚为什么要写函数
举个例子:假设我要写100行代码,伪代码如下:
这样如果我找写第70行代码写什么,只要使用二分法的原理:先找写100行代码(),然后找写51-100行代码();以此类推。
所以我们写函数的目的就在此:把代码分割成小的部分,更容易查找。
这样做有个前提:就是你的函数名必须有意义并且表达准确,否则就更浪费时间,如上文的写1-50行代码()和写51-100行代码()函数名调换,内容不变,识别起来难度就会变大,你先找写1-50行代码(),发现它其实是写后面50行代码,这会让你在逻辑上纠结一段时间,所以再次强调:函数名一定要有意义。
另外还有一点,分割项目不要一次分的太细比如上面的例子,我也可以这样写(为了显示效果,我没写省略号,就一行行写了):
发现了吗?这段代码的可读性明显变差了。所以一般情况下这种分割函数(里面每一句都调用其他函数),分割函数代码不要超过10句,最好不要超过5句。
和分割函数相对应的,还有一种我称作逻辑函数,这种函数都是做具体的工作,一般不要超过20行,如下:
特殊情况1:有一堆的参数赋值/传递:
比如录入个人信息:有身高,体重,爱好,优点,缺点,性别,父名,母名…这种可能会有很多数据,可能远远超过20行,那么,就把这部分代码单独分割:
大概是这样,其实真的无法分割吗?并没有这样说法。上面的内容可分为:身体信息,偏好信息和亲友信息,于是上面的一个UserInfo就可以分割为BodyInfo,LoveInfo和RelativesInfo,于是又可以保持在20行之内了
ヾ(◍°∇°◍)ノ゙
特殊情况2:逻辑分支,回调和异常处理
逻辑分支例子:
回调例子:
异常处理例子:
上面三种情况:选择分支,回调和异常处理都会导致代码臃肿,可读性变差,我通常都会把里面的部分单独列到新的:
第一种:
合成为:输出结果(boolean isRoastDuckInBeijing,String address)
因为条件分支往往好起名字,所以我通常会这样写
第二种:
clickButtonEvent(){}
因为我不能保证除了输出北京烤鸭信息外是否会做些别的什么,通常这部分的修改频率较高
第三种:
public void methodNameThrowException() throw Exception{}
通常我会在原名称后加上ThrowException提醒自己抛出异常,这样既显示了区别也降低层次,看起来更舒服了:
总结:
1.学会用if…else if代替多层次if…else
2.学会用逻辑运算符&&和||代替多层if和多分支if … else if
3.学会用return降低层次
4.函数参数要尽量少,太多的把它合成一个类
5.函数名要易读
6.函数要尽量短小
7.有多层次或多分支的,使用新的函数代替代码块。