代码优化
1.关于命名
1.1 命名一定要符合这个类的作用。最好做到一眼就可以看出这个类的作用。好的命名可以省去注释
1.2 不要用摸棱两可的命名,不要用抽象的命名,宁可名字长一点可以反应这个程序或对象的作用,也不要使用容易误导的短词语
1.3 命名时最好在团队内有一个命名规范或者约定。具有相似作用的类,命名也要相似。例如同样是作为管理的类,就需要命名时统一使用相同的后缀,比如Manager等。这样的话,项目里的代码风格统一,阅读也方便。
2.关于注释
2.1 注释并不是越多越好。优秀的代码是可以不需要注释的。太多的注释反而会影响到代码的可读性,而不准确,过时甚至是错误的注释,更是百害无一利。
2.2 废弃的注释该删掉就删掉。
2.3 冗余的注释也不应该存在,比如说for(int i = 0;i<10;i++) 这里给自变量i去注释就是非常冗余的。
2.4 要写注释就仔细琢磨,使用正确的语法,保证注释能够符合代码的意图。
2.5 注释掉的代码建议删除。因为大部分情况都有可能不会再用到。。若需求改回来了,可以使用源代码版本管理工具来进行代码的还原,而不是把那些废弃的代码注释掉。因为那些东西也很影响代码的阅读和理解。
3.函数
3.1 函数一定要保证短小。太长的函数极其影响对它的职责的理解。
3.2 一个函数只做一件事。随着时间进行函数也许会越来越大,原来只做一件事情的函数后来可能会做越来越多的事情,这种时候就需要对函数进行重构了。让函数保持短小,并只负责一件事情。这也和函数的命名遥相呼应。
3.3 减少重复。将重复的代码单独拧出来做为一个新的函数去被原函数调用,减少重复的代码。这样也是保持函数短小的有利方法。
3.4 函数的参数。最好的函数是没有参数,其次是1个,再次是2个,拥有3个或者3个以上参数的函数,都会令人对函数的作用感到费解。
3.5 如果函数中有那种比较长的条件判断,比如if(conditionA || conditionB && conditionC )类似这样的,可以把这个条件判断单独的抽出来作为一个函数,这样可以提升代码的可阅读性。
3.6 每个函数一个抽象层级。就是一个函数里的代码调用的抽象层级,尽量保持一致。这个要做到很难=。=,笔者表示做不到。
4. 类
4.1 类应该短小。一般,一个类不要超过200行,再多不要超过500行。短小的类容易让人理解,太长了,这个类的作用就太大了,同时复杂度也上升了,难于理解。
4.2 单一权责原则。即一个类只需要负责它自己的职责。一个类太大,方法太多往往也是这个类责任太多的体现。虽然这个原则容易让人理解,但是这个原则也是最容易被不遵守的原则。系统应该有许多短小的类,而不是少量巨大的类组成,每个小类封装一个权责,只有一个修改的原因,并与少数其他类一起统统达成期望的系统行为。
4.3 内聚。它的意思是,如果一个类中的每一个变量都被每一个方法所使用,则该类具有最大的内聚性。但是一般这种极大化的内聚类是不可能的,所以我们希望内聚性保持在较高位置。内聚性高,意味着类中的方法和变量相互依赖,互相结合成一个逻辑整体。这样,保持类的内聚性也会间接的得到许多短小的类。
4.4 类的组织。在一个类中,从上到下各个成员的位置优先级如下: 静态常量 -> 静态成员 ->成员变量 ->公共函数 ->私有函数。函数的位置也不要随便摆。一般公共接口函数紧接着变量的定义,公共函数里引用的其他成员函数根据在本类里出现的前后顺序,依次呈现在类中。
5.其他
5.1 尽量减少重复的代码。利用函数或者多态来重构。
5.2 限制类或者模块中暴露的接口数量,仔细的设计类的接口。不创建拥有大量方法和大量成员变量的类。
5.3 碰到长的switch case 语句或if/else语句,考虑能否用多态的方式来重构,符合开放/闭合原则。
5.4 若函数参数中有选择算子参数时(即在参数里传 bool 类型的参数),使用多个函数来分别处理这些情形通常优于向单个函数传递某些代码来选择函数行为。
5.5 用明明常量来替代魔术数。即不要在代码里出现固定的数字或者字符串常量,而改用常量来定义这些数。例如
const int MaxBuffer = 4096; byte[] buffer = new byte[MaxBuffer];
上面的代码优于下面的:
byte[] buffer = new byte[4096];
当然,有些常识性的数字可以不遵守这样的规定,比如一分钟有60秒,一周有7天,就可以直接将60,7写在代码中
5.6 封装条件。如果没有if 或者while语句的上下文,布尔逻辑就难以理解。应该把解释了条件意图的函数抽离出来。例如:
if ( shouldBeDeleted(timer) ) 要好于 if ( timer.hasExpired() && !timer.isRecurrent() )
5.7 避免否定性条件。否定式要比肯定式难明白一些。例如:
if (buffer.shouldCompact()) 要好于 if ( !buffer.shouldNotCompact) )
5.8 遮蔽时序性耦合。假如有三个函数A,B,C,它们的调用有时序性。比如依次调用 A();B();C();才能正常使用。但是这样是看不出来它们的有调用的先后次序的。将它们改为: a = A(); b = B(a); C(b); 这样,别人在看代码的时候就一目了然。
5.9 避免传递浏览。即我们有时候会写出 a.getB().getC().doSomething()的代码。这样是不好的。好的做法是直接在a类里面添加一个方法,这个方法把上面的事情全部做了。这样外部在调用的事情时,就只需要调用a.doSomething()即可。