- 移除重复代码
- 将注释转换为代码
什么样的类是看代码的人最喜欢的?那就是简单易看的类.一个设计得好的类,能够让人家一眼就能出你这个都有些什么东西,明白你这个类都做了一些什么事.如果看这个类的时候,要不停的将屏幕滚来滚去,而思维还要屏幕的滚动跳转,无形中,看懂这个类需要花的时间就多了.
- 将注释转换为代码,让代码足够清楚到可以表示注释
- 将注释转换为变量名
- 对参数的注释转换为参数名
- 将注释转换为方法的一部分
- 删掉没有用的注释
- 将一部分重复代码重构成方法,用方法名来表示代码的注释
- 用注释去命名一个已经存在的方法
- 同时要避免方法名过长。
为什么要删除额外的注释?其实,加注释本身是一个很正确的事情,因为注释可以让人更容易的理解代码.因为序员觉得光光代码,可能还不能让人完全理解.
而问题就在于,因为常常没有把代码写清楚,所以我们就找了一个捷径,那就是写上注释.注释不够清楚,再写档.好,这样子,程序可以让人看得懂了吧.
而这样造成的结果就是,没有人愿意去好好的组织代码,让代码清楚起来,因为他们觉得加上注释就好了.
之后,代码更新了,可是程序员却常常忘了去更新注释(我们不得不承认,这种情况经常发生,这点,再好的软件都会有这种问题的存在).
过了一段时间,这些过时的注释不仅不能让代码更容易懂,反而会误导了读代码的人.
到了最后,我们剩下的东西就是:本身就不清晰的代码,混上一些不正确的注释。
因此,不管任何时候,当我们要加注释的时候,我们应该再三的想想:
我的注释能不能转化在代码里面,让代码跟注释一样的清晰?
而大多数情况下,我们得到的答案都是:能!
每一个注释都是一个改进代码的好机会!
我们不能说,注释少的代码就是好代码.
但我们绝对可以说,包含太多注释的代码,绝对不是高质量的代码.
- 移除代码异味
要判断代码的稳定性,我们可能会这样来判定:先假设一些具体的情况或者需求变动了,然后来看一看,要满足这些新的需求,代码是否需要被修改?
可惜,这也是一件很麻烦的事,因为有那么多的可能性!我们怎么知道哪个可能性要考虑,哪些不用考虑?有个更简单的方法,如果发现说,我们已经第三次修改这些代码了,那我们就认定这些代码是不稳定的。这样的方法很“懒惰”,而且“被动”!因为这是在我们被伤到了以后,才开始处理问题。虽然这种方法还算一个很有效的方法。
此外,还有一个简单,而且“主动”的方法:如果这段代码是不稳定或者有一些潜在问题的,那么代码往往包含一些明显的痕迹。正如食物要腐坏之前,经常会发出一些异味一样(当然,食物如果有异味了,再怎么处我们都不想吃了。但是代码可不行。)。我们管这些痕迹叫做“代码异味”。并不是所有的食物有异味都不能吃,但大多数情况下,确实是不能吃了。并不是所有的代码异味都是坏事,但大多数情况下,它们确实是坏事情!因此,当我们感觉出有代码异味时,我们必须小心谨慎的检查了。
- 代码用了类别代码(type code)
想要去掉一个类别代码有2中方法:一是为每一种类建立一个子类,二是用一个对象代替一个类别。
- 方法中还有Switch或是一大堆的if else if。Switch表达式一般是跟类别代码一起出现的。
用抽象类或接口通过继承来描述不同的类别以消除Switch或是一大堆的if else if。将不同的类别共同的方法放到父类或接口中,在子类中通过继承去表述不同的意义。
总结一下类别代码的移除
要移除一些类别代码和Switch表达式有2种方法:
1、用基于同一父类的不同子类来代替不同的类别。
2、用一个类的不同对象来代替不同的类别。
当不同的类别具有比较多的不同的行为的时候,用第一种方法。当这些类别的行为非常相似,或者只是差别在一些值上面的时候,用第二种方法。
- 一个类有很多属性有时候是不用的
- 想给变量一个好一点的名字都做不到,因为为不同情况下他们有不同的含义
- 太多的注释
- 方法或类的代码太多或者说太长
- 方法的参数过多
- 2个类彼此引用(依赖于彼此)
- 保持代码简洁
要判断一个类是否需要修整,一个比较主观的方法是:当在读一个类的代码时,看看我们会不会觉得这个类“太长了”,“太复杂了”,或者讲的概念“太多了”?如果会这样觉得的话,我们就认定,这个类需要修整。
另外一个比较简单而且客观的方法是:当发现我们已经在第二次或者第三次扩充这个类的时候,我们认定这个类要修整了。这是一个比较”懒惰,被动”的方法,但却很有效。
单一职责原则(The Single Responsibility Principle)认为:每个类都应该只为一个理由而修改。当一个类包含许多其他的功能时,很明显违反了单一职责原则。
- 慎用继承
- 继承了一些不合适(或者没有用)的功能
当我们继承了一些我们不想要的东西,我们应该再三的想想:他们之间是不是真的有继承的关系?弄清楚父类和子类需要表述的逻辑关系,理清思路。
代理(delegation)
当一个类只是作为一个中间介让外界调用另外一个类中的方法,我们管这样传递调用的中间介叫代理。
用“代理”的优点就是我们可以通过修饰符(public)去控制类中的方法哪些可以“公布”,如果用继承的话就没得选择了。内部可见和外部可见的问题。
- 如果一个父类所描述的东西不是所有的子类所共有的,那这个父类的设计肯定不是一个好的设计。
- 处理不合适的依赖
怎么判断是“不合适的依赖”:
方法一:有没有一些互相循环的引用。具有局限性,并不是所有的“不合适的依赖”的代码都是这种互相依赖。看代码:有没有相互依赖。
方法二:在检查代码的时候我们问自己:对于它已经引用的这些类,是它真正需要引用的吗?认真想想:它真的需要什么。
方法三:在设计类的时候,我们先预测一个以后可能会重用到这个类的系统,然后在那样的系统中去判断,之前的那个类能不能在这里重用?如果你自己都觉得以后的系统不能重用这个类的话,就可以断定这个类包含了“不合适的依赖”。推测一下:它在以后的系统中可以重用吗?
方法四:当我们在一个系统中重用某个类的时候,却发现重用不了,我们就判断该类包含了“不合适的依赖”。到重用的时候就知道了:现在我要重用这个类,能不能重用呢?
依赖反转原则(Dependency Inversion Principle )表述:抽象不应该依赖于具体,高层的比较抽象的类不应该依赖于低层的比较具体的类。当这种问题出现的时候,我们应该抽取出更抽象的一个概念,然后让这两个类依赖于这个抽取出来的概念。
- 将数据库访问、UI和逻辑分离