1.何谓重构?
答:
A.重构(名词意义):对软件内部结构的调整,目的是在不改变软件可观察行为的前提下,提高其理解性,降低其修改成本;
B.重构(动词意义):使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构;
总结:为了更容易理解和修改软件,在不改变软件功能的前提下,调整软件结构;
重构的两种思维:在软件开发的过程中,编码和重构经常会交叉,因为二者是两种不同思维方式,为避免产生思维混乱,最好将二者独立开来:同一时间只做同一件事,要么编程,不做重构;要么重构,不做编程;
评:编程考虑的是实现功能,为此常常可能牺牲结构、性能、扩展性,着眼的是局部等,这都是难免的;重构考虑的是重新梳理软件的功能之间的逻辑和功能内部的实现,着重的是系统,所以更多的是考虑理解性、扩展性、稳定性等;如果二者同时进行的话,可能就会产生考虑过多,导致无法编码或编码艰难;本质上,编码和重构是存在矛盾的,结合我以往的经历来看,同时做两件相互冲突的事,就会丧失思考力,因为你考虑的东西太多,结果反而不知如何是好了!
总评:把软件比作人体,重构就是锻炼身体,可以排除体内的负能量(垃圾、毒素等),也可以提升自身的身体素质,增加器官的活性,提升身体的抵抗力; 你可以去健身房,也可以抽个业余时间;锻炼的目的一般来说有两个:1.改变个人的精神状态,使得身体处于积极状态;2.为了追求身体之美,像古希腊人一样为了追求身体之美而锻炼;
2.为何重构?
A.改进软件设计:软件的设计随着时间的流逝,会逐渐的腐败。当程序员修改和添加功能的时候,着重的是功能的实现。所以无法统揽全局,从系统的角度来考虑修改或添加的模块对整体的影响;所以我们需要重构,来帮助我们不断矫正软件,使之稳定运行;
评:犹如人体之五脏六腑,各官其能,经由血管脉络连贯全身,使人能正常生存并思考;人体的结构是进化的结果,进化总是倾向完美性或适合性的;计算机就是软件的生活环境,如果软件的结构很糟糕,那么软件也是运行的很不开心的。重构就相当于使得软件的结构更加符合计算机的要求;归根到底,在我看来,计算机的结构本身就是人利用思维创造的合理性的实体,也是人的思维的体现;软件也是思维的产品;我们要做的就是让一件产品运行到另外一件产品中;
B.让软件更易理解:软件的运行是在计算机中进行的,但是软件的开发往往是多人开发集成的;所以我们在追求计算机的理解的同时,也要让别人理解。后者往往要比前者花费的时间更长,更影响软件的运行;
评:“幸福家庭家家相似,不幸的家庭各各不同”,合理性对于所有人来说是相同的;所以合理性也是衡量软件质量的一个标准(自我理解),所以,如果别的程序员看不懂我们的软件的时候,在怀疑他人的能里的同时也应该考虑自己的设计是否真的合理;就像1+1 = 2,你可以不喜欢,但是只要你能理解对软件来说就是成功的;
C.提高编程速度:对系统的理解时间要大于编程时间,如果对整个系统胸有成竹,接下来只是写代码的功夫了;
评:语言都是一种世界观,java的面向对象、C的面向过程本质上都是一种对世界的理解;慢慢的就会发现,所谓程序只是用来实现功能,真正困难的还是人对事物的理解和认识;就像王国维的人生三境“看山是山,看水是水”、“看山不是山,看水不是水”、看山还是山,看水还是水“。重构考究的就是程序员的思维境界,看水还是看水全看个人能力;境界高,看待事物的方式不同,解决起来也是容易的很;境界低,只能不断摸索,最后还是执于一隅;
D.重构找到bug:重构就是让软件系统重归合理性之旅,必须梳理清楚软件系统的逻辑,在复归合理性的过程中,我们会逐渐的发现不合理之处(bug)。
总评:为何重构犹如问人为何锻炼身体一样。改进软件设计和重构找到bug,相当于人通过锻炼修复身体的损伤,保证了人的正常功能;让软件更易理解和提高编程速度就相当于改善个人的状态,使得充满激情和正能量;我的感受是一般运动后都会很放松,也更健谈,做事的效率也会提升很多;
3.何时重构?
答:软件程序无非是增删改查,添加和去除功能的时候要重构,一方面是为了下次能更好的理解增加的功能模块,其次也是为了在开发的过程中逐渐的把代码结构理清,便于接下来的开发;修改功能时要重构,调试过程中重构,让代码更具可读性,设想如果程序出错,而我又无法准确定位原因的时候,充分反应了代码不够清晰,无法锁定异常所在;查即代码复查,代码复查类似于”结对编程“,让别人理解你的程序,一方面突破自己的固有思维模式,同时也是判断软件的可读性的一种方式;
4.何时不该重构?
答:
A.现有代码过于混乱,重构的成本大于重写
B.代码在大部分情况下无法正常运行,稍作改动,就报很多错误,无法稳定运作;
C.项目临近交付的时候;
5.重构的难题
A.数据库:数据库重构的难题有二:1.商用软件的数据库和业务关联;2.数据的迁移;
B.修改接口:面向对象的封装性使得程序员可以将功能实现和接口独立开来,接口一旦发布,就很难修改。所以如果功能扩展而旧接口无法满足需求时,一个不坏的方法就是在旧接口中调用新的接口;其次,务必注意,接口发布之先,一定要修改代码所有权政策;
C.难以通过重构手法完成的设计改动:有些项目过大,通过重构完全无法修改程序的设计
6.设计与重构
A.只有设计:结合我自身的项目经历来看,由于初始用户需求不是太明确,项目又略显复杂。所以在开发之初总是想着考虑各种情况,尽量的让软件设计保持灵活;但是最后却发现,在开发的过程中总是会遇到各种问题,这个时候只能是修改设计,开发到最后设计也面目全非了,开发过程中也很累;
B.只有重构:只有重构而不考虑开前的设计倒也可以,一个问题是如果不能熟练的掌握重构,要想在开发过程中很好的重构程序几乎是不可能的;毕竟设计更着重与系统的流程和架构,受业务影响,重构更关注的是功能模块的实现逻辑和模块之间的关系,更偏重技术角度;
C.设计+重构:这种方式会好很多,一方面可以简化设计,同时简化的设计又可以很好的指导开发,在开发的过程中遇到问题也可以通过重构灵活的修改设计;也就是说我们掌握重构后有足够的信心应对需求的变化。
7.重构与性能
重构不一定提升软件性能,但可以使性能提升更容易;性能提升一般有三种方式:
A.时间预算法:预先定义软件各功能模块的时间成本,严格控制,从而提升系统运行时间;对于一般软件来说,无需这种要求;
B.持续关注法:程序员在做任何修改时,必须保证程序的高性能;一般很难实现,因为任何一次的修改如果是为了性能提升的话,通常都会使程序难以维护;如果以此换来程 序的性能提升倒也值得,但是大部分情况下并非如此;性能改善往往着于一角,局部的性能提升了,但是整体的性能却是无法保证;不过就我开发的经历来说,部分性能的 提 升在很大程度上会提升系统性能,当然前提是软件编码很糟糕,有很大的优化空间;
C.根据二八原则,影响程序80%性能的往往是20%的代码;所以初始编码的时候无需耗费过多精力于重构,待编码完成,就集中精力测试,找到影响性能的20%代码,然后采用持续关注法和时间预算法(我认为两种方式可以交叉使用),集中优化;
8.重构源于何处?
你猜!