您的位置:首页 > 编程语言

关于对代码重构的一点看法

2011-08-02 13:13 417 查看
考虑了很久才决定发上来,因为这个话题很有可能会挨一顿批,后来想了想不挨批 ,怎么可以学到东西呢,所以还是决绝的发了上来。

重构这个话题从概念上来说挺好理解,即重新整理自己以前写过的代码,重构的好处不言而喻,它有助于代码的可读性,可维护性,也有利于代码的可调试性,那什么时候该重构,什么样的代码值得重构呢,以及怎样去重构这些代码,这里我谈一下我的看法。

在开发一个系统时,随着代码的不断增长,也为了完成上面布置下来的进度,对于代码的结构上考虑的可能相对就少了点,也许此时问题慢慢的出现了,但因为还能继续下去,所以也只是在心里预算,在以后留下一段时间来专门的做重构,这样是对的吗,我想这确实绝不能算错的,因为这也算是敏捷开发当中的一个思想吧,可很多时候真得到了一定的时候才去重构吗,其实我倒觉得重构应该是无时不在的,当你在要增加一个功能,找到相对应代码时,如果你觉得它对于你增加的这个简单功能需要配置多个地方,或者说在以后增加类似功能时,又不得不写很多相同代码,还有就是你觉得如果你修正了这段代码后,能让代码结构性更清晰,更好的调试,那也许此时你可以考虑重构了,当然对于重构我觉得很多时候还是不能一个人拿主意,因为你必须考虑到你是团队中的一员,所以你更应该与写这段代码的程序员共同商量,因为有些时候,这段代码可能不需要重构,只是因为与你的思维习惯有点不同(很多时候,争论也是因此而产生),如果说,那个程序员在听了你的意见后,也觉得有道理,重构此段代码是对以后的扩展有好处,而且能更好的管理,那这样你还说什么呢,开始重构吧。

什么样的代码需要重构,我想这点很多时候,是可能跟一个程序员的经验来判断的,很多有经验的程序员,在阅读某段代码时,可能很快就可以嗅出这段代码里面的异味,如程序里面大量的充斥着SWITCH语句,代码里面大量的重复代码,大量的临时变量,一个函数从头到结尾几百行,一个CLASS里面完成的功能太多等等,碰到这些代码,我觉得你也可以拿起重构这个武器,对它进行手术般的修整了。

看到需要重构的代码,以及跟团队成员讨论确定可以重构,那此时就可以开始重构了,那怎么才能去重构呢,这也许又是一个问题了,拿我自己来说,我觉得以面向对象的思想去重构可以很好的解决这个问题,面向对象最精髓的就是“抽象”,把一个大的东西以一个模块来对待, 再在大模块里面区分出各个小模块,彼此理清各此的继承关系,以及清楚各个小模块各自的功能,如果可以还可以在小模块里面再划分,只要保证以下几个原则,可维护,可扩展,可复用。

下面我来说一下我遇到的一个案例,以及最后我采取的重构方法(挺简单的,但很有针对性)

我们现在在开发一个系统,里面牵涉到很多的报表,当时也因为工期的问题,对于代码的结构性上面考虑的较少,所以后来准备推翻重来,只是这次重来需要保证几个问题,也就是上面提到的,可扩展,可维护,以及对于特定报表的修改不至于影响到整体报表,考虑到以上几个问题,再具体的查看了以前的代码(虽说以前的代码不具重用性,但可以从中获取这些报表的一些共通点),在仔细查阅后,我发现这些报表可以分为很多种类,而且这些类型的报表都有一个共同点,就是模板里面上部分显示图表,下部分是显示数据。基于这些特点,我开始准备重新设计,首先我确信这些报表应该是可以构成一个模块的概念,而这个大的模块又可以分类成各种报表类型的模块,各种类型的模块呢还可以再分特定的报表,这样结构就可以一下子清晰了,再抽象,上面说了,所有的报表是由两部分组成,即图表与数据两部分,这样我们就可以抽象出基类,只包含两个方法,所有的报表类型都继承于它,所有的特定报表再继承上一层所属的报表类型,这样整个结构
就出来了,文件结构也按照此种思想,新建了一个报表文件夹,里面包含各种类型的文件夹,各个类型文件夹里面又包含了各个具体的报表文件,再通过继承关系,把它们组织起来,最终在外部调用他们,只需要封装一个类,用于专门获取具体的报表对象,然后再对具体的报表对象进行操作,这样就解决了上面提到的几个要求,下面是比较新老两个版本

在旧版本里面,所有的具体报表都是通过SWITCH来判断,各个分支等于处理一个报表,而当时又因为想共用数据部分,最终他们调用的都是同一个获取的数据方法,而因为在页面显示时,数据组织形式又相当的复杂,最后搞得整个MODEL无法查阅,要想再添加一个报表,那简直是不可能的

新版本里面,各个具体的报表操作自己的文件,数据调用也是调用自己的数据模型,数据模型里面只负责数据的取操作,所有的逻辑操作都在具体的报表里面完成,而最外层的调用,也只是调用,不处理任何的逻辑操作,这样等于修改一个报表或者说增加一个报表时,就很有针对性的修改与增加了,再怎么变,再怎么增加也不会影响到其余的报表,当然这个结构可能也只是暂时的适应这个时候,在以后的发展过程中也会不断的提炼。

就说到这吧,反正这就是我的一点理解,相信很多大神们都有自己的意见,因为在这个方面没有一个标准的答案,也许很多同行看到这篇文章,会给出一词“一毛不值”,呵,现在我也不管那么多了,只想着用这篇文章来做一个抛砖引玉,也想多学习一下各种更好的重构手法。

重构(名词):对软件内部结构的一种调整,目的是在不改变"软件之可察行为"前提下,提高其可理解性,降低其修改成本.

  重构(动词):使用一系列重构准则(手法),在不改变"软件之可察行为"前提下,调整其结构.

  两种定义都强调是在不改变"软件的外部行为"前提下,不改变"软件之可察行为"就是说让修改不影响外部使用程序(程序员),在个外部来看,程序的行为和结果没有任何的变化.重构只是对程序内部结构进行调整,让代码更加容易理解,然后更容易维护

我怎么看到的都是“重写”

准备重构——保持项目节奏实践

重构是对代码的简化,无论是产品代码还是测试代码。重构不等于重新设计,只是简化而已。重构过的代码不会改变它的接口,只是更简单。

我的代码不见了

哈尔,初级开发人员

我现在参与的项目是离开学校后的第二个。在第一个项目中,经理听了我的代码工作估算后说:“好,既然你还是个新人,咱们就再多加点儿时间吧,这样你可以把学到的经验应用到写好的代码中。”我觉得他这么做纯属多余,不过没关系,我还是加倍努力,在截止日期来临之时完成了手上的工作。接下来,我了解了整个系统真正的运转方式,就得修改已完成的工作了,不只耗费了所有额外的时间,而且还多用了一点点。让我感到惊讶的是:为了解决问题,我没有编写更多代码,而是简化了现有做法并去掉一些代码。我的代码不见了。

现在这个项目,我使用了持续集成,而且一边开发一边重构。在开发时,简化并清洁代码,而不是改变设计,这让我对自己手上的工作和开发速度有了更清晰的认识。而且,我的代码仍然在继续消失。

如果你曾经随项目进展计算过代码行数,要是项目采取顺序式生命周期,或是将集成和测试放在项目临近结束时进行,那就会看到一个S形曲线(见图9.1)。可以注意到,开始集成和测试后,代码的数量就开始减少了,这是因为发生了重构。(没错,也许是重新设计了某些东西,不过以我的经验,主要是重构造成的。)如果不准备在项目快结束时进行重构,或是不愿意在顺序式生命周期中偿还技术债务,代码量会居高不下。在项目快结束时,代码缩减就不会发生。





图9.1 顺序式生命周期中代码量的典型变化

在使用敏捷生命周期的项目中,代码量的曲线很可能如图9.2所示。代码的增长要慢得多,因为开发人员仅仅编写当前功能需要的代码。他们还会一边开发一边重构,而不是等到项目快结束时再去修复一大堆bug。(对于很多bug来说,去掉某些代码就可以解决。)





图9.2敏捷生命周期中代码量的典型变化

项目经理可以让重构与开发同时进行,也可以最后再进行重构。如果希望发布的产品中缺陷越少越好,就必须要对代码进行重构。如果让重构与开发同时进行,重构的成本是非常小的。如果打算在项目结束时重构,那成本可就高了,而且你会发现总是没有时间去做重构。要么管理层就会指示你不要重构。高昂的成本来源于开发人员得到的反馈延迟过久,以及不知道应该重构哪些代码以及如何重构,因为开发人员很久没有思考过要重构的代码了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: