快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

ag8只为非凡享受:步步为营 .NET 代码重构学习笔记 一、为何要代码重构



一、为什么要重构(Refactoring)

经由过程重构可以达到以下的目标:

1·持续偏纠和改进软件设计

重构和设计是相辅相成的,它和设计彼此互补。有了重构,你仍旧必须做预先的设计,然则不必是最优的设计,只必要一个合理的办理规划就够了,假如没有重构、法度榜样设计会徐徐腐烂变质,愈来愈像断线的鹞子,脱缰的野马无法节制。重构着实便是收拾代码,让所有带着发散倾向的代码回归本位。

2·使代码更易为人所理解

Martin Flower在《重构》中有一句经典的话:"任何一个傻瓜都能写出谋略机可以理解的法度榜样,只有写出人类轻易理解的法度榜样才是优秀的法度榜样员。"对此,笔者感触很深,有些法度榜样员老是能够快速编写出可运行的代码,但代码中晦涩的命名使人晕眩得必要紧握坐椅扶手,试想一个新兵到来接手这样的代码他会不会想当逃兵呢?

软件的生命周期每每必要多批法度榜样员来掩护,我们每每轻忽了这些后来人。为了使代码轻易被他人理解,必要在实现软件功能时做许多额外的事故,如清晰的排版结构,简明扼要的注释,此中命名也是一个紧张的方面。一个很好的法子便是采纳暗喻命名,即以工具实现的功能的依据,用形象化或拟人化的伎俩进行命名,一个很好的立场便是将每个代码元素像新生儿一样命名,大概笔者有点命名偏执狂的倾向,如能荣此雅号,将深以此为幸。

对付那些让人充溢迷茫感以致误导性的命名,必要果决地、大年夜刀阔斧地整容,永世不要部下留情!

3·赞助发明暗藏的代码缺陷

孔子说过:温故而知新。重构代码时强迫你加深理解本来所写的代码。笔者常有写下法度榜样后,却发生对自己的法度榜样逻辑不甚理解的情景,曾为此惊悚过,后来发明这种症状居然是许多法度榜样员常患的"感冒"。当你也发生这样的情形时,经由过程重构代码可以加深对原设计的理解,发明此中的问题和隐患,构建出更好的代码。

4·从长远来看,有助于前进编程效率

当你发明办理一个问题变得非常繁杂时,每每不是问题本身造成的,而是你用错了措施,卑劣的设计每每导致臃肿的编码。

改良设计、前进可读性、削减缺陷都是为了稳住阵脚。优越的设计是成功的一半,停下来经由过程重构改进设计,或许会在当前减缓速率,但它带来的后发上风却是弗成低估的。

二、何时动手重构(Refactoring)

Kent Beckag8只为非凡享受提出了"代码坏味道"的说法,和我们所提出的"步队变形"是同样的意思,步队变形的旌旗灯号是什么呢?以下列述的代码症状便是"步队变形"的强烈旌旗灯号:

1·代码中存在重复的代码

扶植,假犹如一个类中有相同的代码块,请把它提炼成类的一个自力措施,假如不合类中具有相同的代码,请把它提炼成一个新类,永世不要重复代码。

2·过大年夜的类和过长的措施

过大年夜的类每每是类抽象分歧理的结果,类抽象分歧理将低落了代码的复用率。措施是类王国中的诸侯国,诸侯国太大年夜势必动摇中央集权。过长的措施因为包孕的逻辑过于繁杂,差错机率将直线上升,而可读性则直线下降,类的壮实性很轻易被突破。当看到一个过长的措施时,必要设法主见子将其划分为多个小措施,以便于分而治之。

3·牵一毛而必要动满身的改动

当你发明改动一个小功能,或增添一个小功能时,就激发一次代码地震,大概是你的设计抽象度不敷抱负,功能代码太过分散所引起的。

4·类之间必要过多的通讯

A类必要调用B类的过多措施造访B的内部数据,在关系上这两个类显得有点狎昵,可能这两个类本应该在一路,而不应该分家。

5·过度耦合的信息链

"谋略机是这样一门科学,它信托可以经由过程添加一其中心层办理任何问题",以是每每中心层会被过多地追加到法度榜样中。假如你在代码中看到必要获取一个信息,必要一个类的措施调用另一个类的措施,层层挂接,就象输油管一样节节相连。这每每是由于毗连层太多造成的,必要查看就否有可移除的中心层,或是否可以供给更直接的调用措施。

6·各立山头干革命

假如你发明有两个类或两个措施虽然命名不合但却拥有相似或相同的功能,你会发明每每是由于开拓团队和谐不敷造成的。笔者曾经写了一个颇好用的字符串处置惩罚类,但由于没有及时告示团队其他职员,后来发明项目中居然有三个字符串处置惩罚类。革命资本是贵重的,我们不应各立山头干革命。

7·不完美的设计

在笔者刚完成的一个比对报警项目中,曾安排阿朱开拓报警模块,即经由过程Socket向指定的短信平台、语音平台及客户端报警器插件发送报警报文信息,阿朱出色地完成了这项义务。后来用户又提出了实时比对的需求,即要求第三方系统以报文形式向比对报警系统发送哀求,比对报警系统接管并相应这个哀求。这又必要用到Socket报文通讯,因为原本的设计没有将报文通讯模块自力出来,以是无法复用阿朱开拓的代码。后来我及时调剂了这个设计,新增了一个报文收发模块,使系统所有的对外通讯都复用这个模块,系统的整体设计也显得加倍合理。

每个系统都或多或少存在不完美的设计,刚开始可能留意不到,到后来才会逐步凸显出来,此时唯有勇于变动才是最好的前途。

8·缺少需要的注释

虽然许多软件工程的册本常提醒法度榜样员必要防止ag8只为非凡享受过多注释,但这个担心好象并没有什么需要。每每法度榜样员更感兴趣的是功能实现而非代码注释,由于前者更能带来成绩感,以是代码注释每每不是过多而是过少,过于简单。人的影象曲线下降的坡度是陡得吓人的,当过了一段光阴后再转头补注释时,很轻易发生"提笔忘字,愈言且止"的情形。

曾在网上看到过微软的代码注释,其详尽程度让人叹为不雅止,也从中体悟到了微软成功的一个履历。

三、重构(Refactoring)的难题

进修一种可以大年夜幅前进临盆力的新技巧时,你老是难以察觉其不适用的场合。平日你在一个特定场景中进修它,这个场景每每是个项目。这种环境下你很丢脸出什么会造成这种新技巧成效不彰或以致形成迫害。十年前,工具技巧(object tech.)的环境也是如斯。那时假如有人问我「何时不要应用工具」,我很难回答。并非我觉得工具浑然一体、没有局限性 — 我最否决这种盲目立场,而是只管我知道它的好处,但确凿不知道其局限性在哪儿。

现在,重构的处境也是如斯。我们知道重构的好处,我们知道重构可以给我们的事情带来垂手可得的改变。然则我们还没有得到足够的履历,我们还看不到它的局限性。

这一小节比我盼望的要短。暂且如斯吧。跟着更多人学会重构技术,我们也将对??你应该考试测验一下重构,得到它所供给的利益,但在此同时,你也应该不时监控其历程,留意探求重构可能引入的问题。请让我们知道你所蒙受的问题。跟着对重构的懂得日益ag8只为非凡享受增多,我们将找出更多办理法子,并清楚知道哪些问题是真正难以办理的。

1·数据库(Databases)

在「非工具数据库」(nonobject databases)中,办理这个问题的法子之一便是:在工具模型(object model)和数据库模型(database model)之间插入一个分隔层(separate layer),这就可以隔离两个模型各自的变更。进级某一模型时无需同时进级另一模型,只需进级上述的分隔层即可。这样的分隔层会增添系统繁杂度,但可以给你很大年夜的机动度。假如你同时拥有多个数据库,或假如数据库模型较为繁杂使你难以节制,那么纵然不进行重构,这分隔层也是很紧张的。

2·改动接口(Changing Interfaces)

「保留旧接口」的法子平日可行,但很烦人。最少在一段光阴里你必须建造(build)并掩护一些额外的函数。它们会使接口变得繁杂,使接口难以应用。还好我们有另一个选择:不要宣布(publish)接口。当然我不是说要完全禁止,由于很显着你必得宣布一些接口。假如你正在建造供外部应用的APIs,像Sun所做的那样,肯定你必得宣布接口。我之以是说只管即便不要宣布,是由于我经常看到一些开拓团队公开了太多接口。我曾经看到一支三人团队这么事情:每小我都向别的两人公开宣布接口。这使他们不得不常常往返掩护接口,而着实他们蓝本可以直接进入法度榜样库,径行改动自己治理的那一部分,那会轻松许多。过度强调「代码拥有权」的团队经常会犯这种差错。宣布接口很有用,但也有价值。以是除非真有需要,别宣布接口。这可能意味必要改变你的代码拥有权不雅念,让每小我都可以改动别人的代码,以运应接口的篡改。以过错(成对)编程(Pair Programming)完成这统统平日是个好主见。

3·难以经由过程重构伎俩完成的设计篡改

经由过程重构,可以扫除所有设计差错吗?是否存在某些核心设计决策,无法以重构伎俩改动?在这个领域里,我们的统计数据尚不完备。当然某些环境下我们可以很有效地重构,这经常令我们倍感惊疑,但切实着实也有难以重构的地方。比如说在一个项目中,我们很难(但照样有可能)将「无安然需求(no security requirements)环境下构造起来的系统」重构为「安然性优越的(good security)系统」。

这种环境下我的法子便是「先想象重构的环境」。斟酌候选设计规划时,我会问自己:将某个设计重构为另一个设计的难度有多大年夜?假如看上去很简单,我就不必太担心选择是否适合,于是我就会选最简单的设计,哪怕它不能覆盖所有潜在需求也不要紧。但假如预先看不到简单的重构法子,我就会在设计上投入更多力气。不过我发明,这种环境很少呈现。

4·何时不该重构?

无意偶尔候你根本不应该重构 — 例如当你应该从新编写所有代码的时刻。无意偶尔候既有代码其实太纷乱,重构它还不如重新写一个来得简单。作出这种抉择很艰苦,我承认我也没有什么好准则可以判断何时应该放弃重构。

重写(而非重构)的一个清楚讯号便是:现有代码根本不能正常运作。你可能只是试着做点测试,然后就发今世码中满是差错,根本无法稳定运作。记着,重构之前,代码必须最少能够在大年夜部分环境下正常运作。

一个协调法子便是:将「大年夜块头软件」重构为「封装优越的小型组件」。然后你就可以一一对组件作出「重构或重修」的抉择。这是一个颇具盼望的法子,但我还没有足足数据,以是也无法写出优秀的指示原则。对付一个紧张的古老系统,这肯定会是一个很好的偏向。

别的,假如项目已近着末刻日,你也应该避免重构。在此机会,从重构历程赢得的临盆力只有在着末刻日过后才能表现出来,而那个时刻已经时不我予。Ward Cunningham对此有一个很好的见地。他把未完成的重构事情形容为「债务」。很多公司都必要告贷来使自己更有效地运转。然则告贷就得付利息,过于繁杂的代码所造成的「掩护和扩展的额外开销」便是利息。你可以遭遇必然程度的利息,但假如利息太高你就会被压垮。把债务治理好是很紧张的,你应该随时经由过程重构来了偿一部分债务。

假如项目已经异常靠近着末刻日,你不应该再分心于重构,由于已经没有光阴了。不过多个项目履历显示:重构切实着实能够前进临盆力。假如着末你没有足够光阴,平日就表示你着实早该进行重构。

代码坏味道

1、重复的代码.

假如你在一个以上的地点看到相同的法度榜样布局,那么可以肯定:设法将他们合二为一.

2、过长的函数.

越短的函数会存活的光阴更长,存活的更好.

3、过长的类.

假如想使用单一的类做很多的工作,那么该类的内部会呈现很多的instance变量,重复代码就要纷至沓来了.

4、过长的参数列.

太长的参数列难以理解,太多的参数会造成前后不同等,不易应用,一旦你必要更多的数据,就不得不改动它.

5、发散式变更.

一旦我改动软件,我盼望只在一处改动就好,假如不能做到这点,该坏味道就呈现了.\

6、烟雾弹式改动.

一旦软件进行改动,你必须去对多个类的内部做小改动,该坏味道呈现了.

7、迷恋情结.

函数对某个类的兴趣高过对自己所处之host类的兴趣,坏味道呈现了.`

8、数据泥团.

两个类中的相同值域,多个函数中的相同参数,该坏味道呈现了.

9、基础种别偏执.

假如一个类只为了做一两件事而创建,却付出了太大年夜的额外开销,该坏味道呈现了.

10、switch惊悚现身.

只管即便少用switch语句,由于switch语句的问题在于重复.

11、平行承袭体系.

假如你发明某个承袭体系的类名称前缀和另一个承袭的类名称前缀完全相同,坏味道呈现了.

12、冗赘类.

假如一个类的所得不值其身价,消掉吧.

13、夸夸其谈未来性.

14、令人含混的暂时价域.

某个instance变量仅为某种特定环境而设置.

15、过度耦合的消息链.

16、中心转手人.

憎恶的封装,对外部天下暗藏其内容.

17、狎昵关系.

两个类过于亲密,花费太多的光阴去商量彼此的似有因素.

18、异曲同工的类.

假如两个措施做同一件事,却有不合的名字.

19、不完美的法度榜样类库.

20、纯稚的数据类.

该类的特点是,拥有一些值域,一级用于造访这些值域的函数,其他的空空如也.

21、被回绝的遗赠.

子类应该一连袭父类的措施和数据,然则父类都写成似有的,不盼望子类承袭,坏味道呈现了.

22、过多的注释.

你发明一个类有很多的注释,是由于这个类很烂,那么这里的注释便是坏味道了.

代码重构相关册本

《work effectively with legacy code》 改动代码的艺术

《The Programtic Programmer From JoumeyMan to Master》 法度榜样员修炼之道

《Pattern-Orieag8只为非凡享受nted Software Architecture Volume 4》 面向模式的软件架构 卷4

《Agile Principles、Patterns and Practice in C#》 敏捷软件开拓 原则、模式与实践(C#版)

《Code Quality The Open Source Perspective》 高质量法度榜样设计艺术

《Refactoring ag8只为非凡享受improving the Designe of Existing Code》重构 改良既有代码的设计

《Design Patterns Explained 》 设计模式解析

《反模式 危急中软件、架构和项目的重构》

《Refactoring to Patterns》 重构与模式

《More Programming Pearls》 编程珠玑II

《Programming Pearls》 编程珠玑(第2版)

《Beginning Java Objects》 中文版:从观点到代码(第2版)

《设计模式解析(第2版)》

《敏捷软件开拓:原则、模式与实践(C#版)》

《Java设计模式》

《重构与模式》

《UML面向工具建模与设计(第2版)》

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: