这段时间一直在做系统重构的工作,记录下重构的思想和感悟。
什么是代码重构?
这里引用维基百科的话:“对软件代码做任何更动以增加可读性或者简化结构而不影响输出结果”。
重构既不修正错误,又不增加新的功能性。反而它是用于提高代码的可读性或者改变代码内部结构与设计,并且移除死代码,使其在将来更容易被维护。重构代码可以是结构层面或是语意层面,不同的重构手段施行时,可能是结构的调整或是语意的转换,但前提是不影响代码在转换前后的行为。特别是,在现有的程序的结构下,给一个程序增加一个新的行为可能会非常困难,因此开发人员可能先重构这部分代码,使加入新的行为变得容易。
为什么代码需要重构?
由于业务的不断变化需求不断的增加,导致后期的代码维护修改变得更加困难,有时候一个简单的功能,以前做过类似的,但会有少许的改动。经过开发、测试、回归,上线有可能也需要几天。
由于前期为了快速上线,没考虑到更多的扩展,没用到任何设计模式,针对不通的逻辑通过 if 判断处理,导致代码越来越庞大,代码可读性和可维护性变得越来越差,每次一点改动都害怕影响到其他功能,有的时候还不能给出印象的范围,导致测试同学也非常的辛苦,需要回归很多功能。
如果对现有代码很难添加新的行为,个人觉得就应该对现有代码逻辑进行重构,因为重构也是需要时间来支撑的,应该选择经常修改并且有时间的时候来重构相关代码。那应该怎么进行重构?重构要达到的目的是什么?下面说说我个人的意见。
重构的原则
面向接口编程:意思就是对外层提供接口,定义好入参和返回值,屏蔽底层的实现细节,调用方根本不需要知道和了解这个接口方法的具体实现,全交由实现类去自定义实现。这样设计的好处一个是解耦,一个是可以多实现(java是一门多态的语言)。
单一职责:也就是一个类只做一件事情,清楚的划分每个类自己的任务是什么,跟它相关的功能代码才可以放入该类中。这样设计的好处是类职责清晰,一看到这个类就知道是干什么用的,代码可读性和可维护性高。
接口隔离原则:一个接口中的所有方法都应该是为完成一件事情而定义的,接口中的方法不会是跟这件事情无关的。这样的好处是接口的职责清晰,不会导致什么方法都往里加,从而代码量少,后期维护和代码可读性变高。
重构的方法
封装成员变量:变量重写成私有成员变量,并提供访问方法。这种重构方式可以将与外部调用者无关的变量隐藏起来,减少代码的耦合性,并减少意外出错的概率。
提取方法:将大段代码中的一部分提取后,构成一个新方法。这种重构可以使整段程序的结构变得更清晰,从而增加可读性。
抽象出公用的基类:将多个类/函数共用的类型抽象出可以公用的基类,然后利用多态性追加每个类/函数需要的特殊函数。这种重构可以让结构更加清晰,同时可以增加代码的可维护性。
方法上移:把公用的方法从子类移动到父类,大家都有的放入父类中,子类可重复使用。
方法下移:把子类独有的方法从父类移动到子类,划分好方法的边界,子类独有的只存在于子类。
方法更名:将方法名称以更好的表达它的用途,俗话说见名知意。
当然,在开发中我们也可以适当的使用设计模式,使用设计模式的关键点是让代码可读、可维护、可扩展。
总结
重构就是对现有代码进行分解、抽象,定义好设计原则,找出它们的共同点,划分好每个类自己的职责,然后在用合适的设计模式对代码进行重新组合的过程。
不要忘记重构的目的是为了以后新加功能时更容易,让新功能可以尽快上线,代码的结构清晰,让代码变得可读、可维护、可扩展。代码重构实际是在为以后做准备,当然,如果代码用一次就不用的,或者很少用的话,我觉得是没有必要重构的,还不如用这些时间去多想想核心功能的开发,也类似系统性能的二八原则。
PS:
清山绿水始于尘,博学多识贵于勤。
微信公众号:「清尘闲聊」。
欢迎一起谈天说地,聊代码。