如何处理前任程序员留下的代码
来源:原创 时间:2017-10-30 浏览:0 次作为软件工程师不可防止会遇到的一个场景是:我们在改动或增加一个功用到不是我们创立的、我们不熟悉的、与我们担任的体系部分无关的代码中时,会遇到费事。尽管这可能会是一个繁琐而艰巨的使命,可是由于运用其他开发人员编写的代码有很大的灵活性,所以我们能够从中得到大大的长处,包括增加我们的影响规模,修正软件腐朽以及学习我们曾经不了解的体系部分(更何况,还能够学习其他程序员的技能和技巧)。
考虑到运用其他开发人员编写的代码既有其厌烦之处,又有其优势地点,所以我们有必要当心不要犯一些严峻的过错:
我们的自我意识:我们可能会觉得自己知道得最多,但一般现实并非如此。我们要更改的是我们知之甚少的代码——我们不知道原作者的目的、导致此代码的决议计划以及原作者在写代码时可用的东西和结构,等等。谦逊的质量无价之宝,你值得具有。
原作者的自我意识:我们行将触摸的代码是由另一个开发人员所编写的,另一种风格、束缚、期限和个人日子(耗费他或她作业之外的时刻)。只需当我们开端质疑他或她做出的决议或质疑代码为什么这么不洁净的时分,那人才会自我检讨,不至于自高自大。我们应该尽悉数尽力让原作者协助我们作业,而不是阻碍我们。
对不知道的惊骇:许多时分,我们即将触摸的代码是我们知之甚少或彻底一窍不通的。令人惧怕的是:我们将对我们所做的任何改动担任,可是我们基本上就像是在没有光线的漆黑屋子里走动一样。其实我们不需求忧虑,而是应该构建一种使我们能够在大小纷歧的改动中感到舒适的结构,并答应我们保证没有损坏现有的功用。
由于开发人员,包括我们自己,是人,所以在处理其他开发人员编写的代码时,处理好许多人的天分问题是很有用的。在这篇文章中,我们将经过我们能够运用的五种技能来保证将对人道的了解成为我们的优势,从现有代码和原作者罗致尽可能多的协助,并使得其他开发人员编写的代码终究变得比正本更优异。尽管这儿列出的5个办法并不全面,可是运用下面的技能将保证在完毕改动其他开发人员编写的代码时,我们有决心坚持现有功用的作业状况,一同保证我们的新功用与现有的代码库协调一致。
work-with-someone-else-code
1.保证测验的存在
要想保证在其他开发人员编写的代码中所存在的现有功用实践能够依照预期的办法作业,而且我们对其进行的任何更改都不会影响到功用的完结,仅有真实令人决心十足的办法是用测验来支撑代码。当我们遇到另一位开发人员编写的代码时,代码有两种所在的状况:(1)没有满足的测验水平,或(2)有满足的测验水平。遇到前一种状况,我们得担任创立测验,而在后一种状况下,我们能够运用现有的测验来保证我们做出的任何更改都不会损坏代码,并尽可能多地从测验去了解代码的目的。
创立新测验
这是一个哀痛的比如:我们在改动其他开发人员的代码时,要对更改成果担任,可是我们没有办法保证我们在进行更改时不损坏任何东西。诉苦是没有用的。不管我们发现代码处在什么样的条件下,我们总之是要触摸代码,因而如果代码坏掉了,就是我们的责任。所以我们在改动代码时,一定要掌控自己的行为。断定不会损坏代码的仅有办法是自己写测验。
尽管这是庸俗的,但它答应我们经过编写测验来学习,这是它的首要长处。假定代码现在能够正常作业,而我们需求编写测验,以便预期的输入会导致预期的输出。在我们完结这个测验的进程中,我们逐步了解到代码的目的和功用。例如,给出以下代码
我们对代码的目的以及为什么在代码中运用Magic number知道得并不多,可是我们能够创立一组测验,已知输入发生已知输出。例如,经过做一些简略的数学和处理构成成功的阈值薪水问题,我们发现如果一个人的年纪在30岁以下,且每年大约赚68,330美元,那么他被认为是成功的(依照本规范的规范)。尽管我们不知道那些magic number是什么,可是我们知道它们的确削减了初始的薪水值。因而,68,330美元的阈值是扣除前的基本工资。经过运用这些信息,我们能够创立一些简略的测验,例如:
经过这三个测验,我们现在对现有代码的作业办法有了大致的了解:如果一个人不到30岁,且每年赚$ 68,300,那么他被认为是成功人士。尽管我们能够创立更多的测验来保证临界状况(例如空白年纪或工资)功用正常,可是一些简略的测验不只使我们了解了原始功用,还给出了一套自动化测验,可用于保证在对现有代码进行更改时,我们不会损坏现有功用。
运用现有测验
如果有满足的代码测验组件,那么我们能够从测验中学到许多东西。正如我们创立测验一样,经过阅览测验,我们能够了解代码如安在功用层面上作业。此外,我们还能够知道原作者是怎么让代码运转的。即便测验是由原作者以外的人(在我们触摸之前)编撰的,也依然能够为我们供给关于其他人对代码的观点。
尽管现有的测验能够供给协助,但我们依然需求对此持保存情绪。测验是否与代码的开发更改一同与时俱进是很难说的。如果是的话,那么这是一个很好的了解根底;如果不是,那么我们要当心不要被误导。例如,如果初始的工资阈值是每年75,000美元,而后来更改为我们的68,330美元,那么下面这个过期的测验可能会使我们误入歧途:
这个测验仍是会经过的,但没有了预期的效果。经过的原因不是由于它正好是阈值,而是由于它超出了阈值。如果此测验组件包括这样一个测验用例:当薪水低于阈值1美元时,过滤器就回来false,这样第二个测验将会失利,标明阈值是过错的。如果套件没有这样的测验,那么陈腐的数据会很简略误导我们弄错代码的真实目的。当有疑问时,请信任代码:正如我们之前所表述的那样,求解阈值标明测验没有对准实践阈值。
别的,要检查代码和测验用例的存储库日志(即Git日志):如果代码的终究更新日期比测验的终究更新日期更近(对代码进行了严重更改,例如更改阈值),则测验可能现已过期,应慎重检查。留意,我们不应该彻底忽视测验,由于它们或许依然能为我们供给关于原作者(或最近编撰测验的开发人员)目的的一些文档,但它们可能包括过期或不正确的数据。
2.与编写代码的人沟通
在触及多个人的任何作业中,沟通至关重要。不管是企业,越野游览仍是软件项目,缺少沟通是危害使命最有用的手法之一。即便我们在创立新代码时进行沟通,可是当我们触摸现有的代码时,危险会增加。由于此刻我们对现有的代码并不太了解,因而我们所了解的内容可能是被误导的,或只代表了其间的一小部分。为了真实了解现有的代码,我们需求和编写它的人沟通。
当开端提出问题时,我们需求断定问题是详细的,而且旨在完结我们了解代码的方针。例如:
这个代码片段最适合放到体系的哪里?
你有什么规划或图表吗?
我应该留意什么圈套?
这个组件或类是做什么的?
有没有什么你想放到代码里,但其时没有做的?为什么?
一直要坚持谦善的情绪,活跃寻求原作者真实的答案。简直每个开发人员都碰到过这样的场景,他或她看着他人的代码,自问自答:“为什么他/她要这样做?为什么他们不这样做?”然后花几个小时来得出正本只需原作者答复就能得到的定论。大多数开发人员都是有才调的程序员,所以即便如果我们遇到一个看似糟糕的决议,也有可能有一个很好的理由(可能没有,但研讨他人的代码时最好假定他们这样做是有原因的;如果真的没有,我们能够经过重构来改动)。
沟通在软件开发中起非有必要副效果。1967年开端由Melvin Conway创立的康威规律规矩:
规划体系的任何安排…都将不可防止地发生一种规划,该规划结构反映了安排的通讯结构。
这意味着,一个巨大、严密沟通的团队可能会生成一体化,严密耦合的代码,但一些较小的团队可能会生成更独立、松懈耦合的代码(有关此相关性的更多信息,请参阅《Demystifying Conway’s Law》)。关于我们来说,这意味着我们的通讯结构不只影响特定的代码段,也影响整个代码库。因而,与原作者亲近沟通肯定是一个好办法,但我们应该自检不要太过于依赖于原作者。这不只可能会惹恼原作者,还可能在我们的代码中发生无意识的耦合。
尽管这有助于我们深入研讨代码,但这是在假定能够触摸原作者的状况下。在许多时分,原作者可能现已脱离了公司,或恰巧不在公司(例如正在度假)。在此种状况下我们该做什么?问询可能对代码有所了解的人。这个人纷歧定要曾真实作业于代码,他能够是在原作者编写代码时就在周围,也能够是知道原作者。哪怕仅是从原开发者周围的人中得到只言片语,也可能会启迪其他不知道的代码片段。
3.删去一切正告
心思学中有一个众所周知的概念,称为“破窗理论”,Andrew Hunt和Dave Thomas在《 The Pragmatic Programmer 》(第4-6页)中详细描绘了这个概念。这个理论开端是由James Q.Wilson和George L. Kelling提出的,描绘如下:
假定有一个建筑物有几扇破了的窗户。如果窗户没有修好,那么损坏者会趋向于打破更多的窗户。终究,他们乃至可能会破门而入,如果建筑物是没人住的,那么他们可能会非法占有或许在里面焚烧。也能够考虑人行道的状况。如果道路上面有废物堆积,那么不久之后,就会有更多的废物累积。终究,人们乃至会开端往那里扔外卖废物,乃至打破轿车。
这个理论指出,如果好像现已没人关怀这个物品或事物,那么我们就会忽视对物品或事物的照料,这是人的天分。例如,如果一栋建筑物看上去现已凌乱不堪,那么它更有可能被任意损坏。在软件方面,这个理论意味着如果开发人员发现代码现已是一团糟,那么人的赋性会让他弄坏代码。从实质上说,我们心里想的是(即便心思活动没有这么丰厚),“已然终究一个人不在乎这代码,我为什么要在乎?”或“都是乱糟糟的代码,谁知道是谁写的。”
可是,这不应该成为我们的托言。只需我们触摸曾经归于其他人的代码,那么我们就要对这些代码担任,而且如果它不能有用作业的话,我们得背负结果。为了打败这种人的天分行为,我们需求采纳一些小办法以防止我们的代码更少地被弄脏(及时替换破掉的窗户)。
一个简略办法是删去来自我们正在运用的整个包或模块中的一切正告。至于未运用或增加注释的代码,删去它。如果我们稍后需求这部分代码,那么在存储库中,我们总是能够从从前的提交中检索它。如果存在无法直接处理的正告(例如原始类型正告),那么运用@SuppressWarnings注解注释该调用或办法。这样能够保证我们对代码进行过细心的考虑:它们不是由于疏忽而宣布的正告,而是我们明确地留意到了正告(如原始类型)。
一旦我们删去或明确地制止一切正告,那么我们就有必要保证代码坚持革除正告。这有两个首要效果:
迫使我们细心考虑我们创立的任何代码。
削减代码糜烂的改动,现在的正告会导致今后的过错。
这对其他人,以及我们自己都有心思暗示效果——我们其实关怀我们正在处理的代码。它不再是条单行线——我们强逼着自己更改代码,提交,然后永不回头。相反,我们知道到我们需求对这代码担任。这对之后的软件开发也是有协助的——它向将来的开发人员展现,这不是一间窗户都破了的库房:而是一个保护杰出的代码库。
4.重构
在曩昔几十年中,重构现已成为了一个十分重要的术语,而且最近被当作是对当时作业代码做任何改动的代名词。尽管重构的确触及对当时正在作业的代码的更改,但并非整个全局。Martin Fowler在他关于这个论题的重要着作——《Refactoring》一书中将重构界说为:
对软件的内部结构进行更改,使其更简略了解而且修正起来更廉价,而不改动其可调查的行为。
这个界说的关键在于它触及的更改不会改动体系可调查的行为。这意味着当我们重构代码时,我们有必要要有办法来保证代码的外部可见行为不会改动。在我们的比如中,这意味着是在我们承继或自己开发的测验套件中。为了保证我们没有改动体系的外部行为,每逢我们进行改动时,都有必要从头编译和履行我们的悉数测验。
此外,并不是我们所做的每一个改动都被认为是重构。例如,重命名办法以更好地反映其预期用处是重构,但增加新功用不是。为了看到重构的长处,我们将重构SuccessfulFilter。履行的第一个重构是提取办法,以更好地封装个人净工资的逻辑:
在我们进行这种改动之后,我们从头编译并运转我们的测验套件,测验套件将持续经过。现在更简略看出,成功是经过一个人的年纪和净薪酬界说的,可是getNetSalary办法好像并不像Person类一样归于SuccessfulFilter(指示标志就是该办法的仅有参数是Person,该办法的仅有调用是Person类的办法,因而对Person类有很强的亲和力)。 为了更好地定位这个办法,我们履行一个Move办法将其移动到Person类:
为了进一步整理此代码,我们对每个magic number履行符号常量替换magic number行为。为了知道这些值的意义,我们可能得和原作者沟通,或许向具有满足范畴常识的人讨教,以引领正确的方向。我们还将履行更多的提取办法重构,以保证现有的办法尽可能简略。
从头编译和测验,发现体系依然依照预期的办法作业:我们没有改动外部行为,可是我们改进了代码的可靠性和内部结构。有关更杂乱的重构和重构进程,请参阅Martin Fowler的Refactoring Guru网站。
5.当你脱离的时分,代码比你发现它的时分更好
终究这个技能在概念上十分简略,但在实践中很困难:让代码比你发现它的时分更好。当我们整理代码,特别是他人的代码时,我们大多会增加功用,测验它,然后前行,不关怀我们会不会奉献软件腐朽,也不在乎我们增加到类的新办法会不会导致额定的紊乱。因而,本文的悉数内容可总结为以下规矩:
每逢我们修正代码时,请保证当你脱离的时分,代码比你发现它的时分更好。
前面提到过,我们需求对类形成的损坏和对改动的代码担任,如果它不能作业,那么修正是我们的责任。为了打败随同软件出产而呈现的熵,我们有必要强制自己做到脱离时的代码比我们发现它的时分更佳。为了不躲避这个问题,我们有必要归还技能债款,保证下一个触摸代码的人不需求再付出代价。说不定,将来可能是我们自己感谢自己这个时分的坚持呢。作为软件工程师不可防止会遇到的一个场景是:我们在改动或增加一个功用到不是我们创立的、我们不熟悉的、与我们担任的体系部分无关的代码中时,会遇到费事。尽管这可能会是一个繁琐而艰巨的使命,可是由于运用其他开发人员编写的代码有很大的灵活性,所以我们能够从中得到大大的长处,包括增加我们的影响规模,修正软件腐朽以及学习我们曾经不了解的体系部分(更何况,还能够学习其他程序员的技能和技巧)。
考虑到运用其他开发人员编写的代码既有其厌烦之处,又有其优势地点,所以我们有必要当心不要犯一些严峻的过错:
我们的自我意识:我们可能会觉得自己知道得最多,但一般现实并非如此。我们要更改的是我们知之甚少的代码——我们不知道原作者的目的、导致此代码的决议计划以及原作者在写代码时可用的东西和结构,等等。谦逊的质量无价之宝,你值得具有。
原作者的自我意识:我们行将触摸的代码是由另一个开发人员所编写的,另一种风格、束缚、期限和个人日子(耗费他或她作业之外的时刻)。只需当我们开端质疑他或她做出的决议或质疑代码为什么这么不洁净的时分,那人才会自我检讨,不至于自高自大。我们应该尽悉数尽力让原作者协助我们作业,而不是阻碍我们。
对不知道的惊骇:许多时分,我们即将触摸的代码是我们知之甚少或彻底一窍不通的。令人惧怕的是:我们将对我们所做的任何改动担任,可是我们基本上就像是在没有光线的漆黑屋子里走动一样。其实我们不需求忧虑,而是应该构建一种使我们能够在大小纷歧的改动中感到舒适的结构,并答应我们保证没有损坏现有的功用。
由于开发人员,包括我们自己,是人,所以在处理其他开发人员编写的代码时,处理好许多人的天分问题是很有用的。在这篇文章中,我们将经过我们能够运用的五种技能来保证将对人道的了解成为我们的优势,从现有代码和原作者罗致尽可能多的协助,并使得其他开发人员编写的代码终究变得比正本更优异。尽管这儿列出的5个办法并不全面,可是运用下面的技能将保证在完毕改动其他开发人员编写的代码时,我们有决心坚持现有功用的作业状况,一同保证我们的新功用与现有的代码库协调一致。
work-with-someone-else-code
1.保证测验的存在
要想保证在其他开发人员编写的代码中所存在的现有功用实践能够依照预期的办法作业,而且我们对其进行的任何更改都不会影响到功用的完结,仅有真实令人决心十足的办法是用测验来支撑代码。当我们遇到另一位开发人员编写的代码时,代码有两种所在的状况:(1)没有满足的测验水平,或(2)有满足的测验水平。遇到前一种状况,我们得担任创立测验,而在后一种状况下,我们能够运用现有的测验来保证我们做出的任何更改都不会损坏代码,并尽可能多地从测验去了解代码的目的。
创立新测验
这是一个哀痛的比如:我们在改动其他开发人员的代码时,要对更改成果担任,可是我们没有办法保证我们在进行更改时不损坏任何东西。诉苦是没有用的。不管我们发现代码处在什么样的条件下,我们总之是要触摸代码,因而如果代码坏掉了,就是我们的责任。所以我们在改动代码时,一定要掌控自己的行为。断定不会损坏代码的仅有办法是自己写测验。
尽管这是庸俗的,但它答应我们经过编写测验来学习,这是它的首要长处。假定代码现在能够正常作业,而我们需求编写测验,以便预期的输入会导致预期的输出。在我们完结这个测验的进程中,我们逐步了解到代码的目的和功用。例如,给出以下代码
我们对代码的目的以及为什么在代码中运用Magic number知道得并不多,可是我们能够创立一组测验,已知输入发生已知输出。例如,经过做一些简略的数学和处理构成成功的阈值薪水问题,我们发现如果一个人的年纪在30岁以下,且每年大约赚68,330美元,那么他被认为是成功的(依照本规范的规范)。尽管我们不知道那些magic number是什么,可是我们知道它们的确削减了初始的薪水值。因而,68,330美元的阈值是扣除前的基本工资。经过运用这些信息,我们能够创立一些简略的测验,例如:
经过这三个测验,我们现在对现有代码的作业办法有了大致的了解:如果一个人不到30岁,且每年赚$ 68,300,那么他被认为是成功人士。尽管我们能够创立更多的测验来保证临界状况(例如空白年纪或工资)功用正常,可是一些简略的测验不只使我们了解了原始功用,还给出了一套自动化测验,可用于保证在对现有代码进行更改时,我们不会损坏现有功用。
运用现有测验
如果有满足的代码测验组件,那么我们能够从测验中学到许多东西。正如我们创立测验一样,经过阅览测验,我们能够了解代码如安在功用层面上作业。此外,我们还能够知道原作者是怎么让代码运转的。即便测验是由原作者以外的人(在我们触摸之前)编撰的,也依然能够为我们供给关于其他人对代码的观点。
尽管现有的测验能够供给协助,但我们依然需求对此持保存情绪。测验是否与代码的开发更改一同与时俱进是很难说的。如果是的话,那么这是一个很好的了解根底;如果不是,那么我们要当心不要被误导。例如,如果初始的工资阈值是每年75,000美元,而后来更改为我们的68,330美元,那么下面这个过期的测验可能会使我们误入歧途:
这个测验仍是会经过的,但没有了预期的效果。经过的原因不是由于它正好是阈值,而是由于它超出了阈值。如果此测验组件包括这样一个测验用例:当薪水低于阈值1美元时,过滤器就回来false,这样第二个测验将会失利,标明阈值是过错的。如果套件没有这样的测验,那么陈腐的数据会很简略误导我们弄错代码的真实目的。当有疑问时,请信任代码:正如我们之前所表述的那样,求解阈值标明测验没有对准实践阈值。
别的,要检查代码和测验用例的存储库日志(即Git日志):如果代码的终究更新日期比测验的终究更新日期更近(对代码进行了严重更改,例如更改阈值),则测验可能现已过期,应慎重检查。留意,我们不应该彻底忽视测验,由于它们或许依然能为我们供给关于原作者(或最近编撰测验的开发人员)目的的一些文档,但它们可能包括过期或不正确的数据。
2.与编写代码的人沟通
在触及多个人的任何作业中,沟通至关重要。不管是企业,越野游览仍是软件项目,缺少沟通是危害使命最有用的手法之一。即便我们在创立新代码时进行沟通,可是当我们触摸现有的代码时,危险会增加。由于此刻我们对现有的代码并不太了解,因而我们所了解的内容可能是被误导的,或只代表了其间的一小部分。为了真实了解现有的代码,我们需求和编写它的人沟通。
当开端提出问题时,我们需求断定问题是详细的,而且旨在完结我们了解代码的方针。例如:
这个代码片段最适合放到体系的哪里?
你有什么规划或图表吗?
我应该留意什么圈套?
这个组件或类是做什么的?
有没有什么你想放到代码里,但其时没有做的?为什么?
一直要坚持谦善的情绪,活跃寻求原作者真实的答案。简直每个开发人员都碰到过这样的场景,他或她看着他人的代码,自问自答:“为什么他/她要这样做?为什么他们不这样做?”然后花几个小时来得出正本只需原作者答复就能得到的定论。大多数开发人员都是有才调的程序员,所以即便如果我们遇到一个看似糟糕的决议,也有可能有一个很好的理由(可能没有,但研讨他人的代码时最好假定他们这样做是有原因的;如果真的没有,我们能够经过重构来改动)。
沟通在软件开发中起非有必要副效果。1967年开端由Melvin Conway创立的康威规律规矩:
规划体系的任何安排…都将不可防止地发生一种规划,该规划结构反映了安排的通讯结构。
这意味着,一个巨大、严密沟通的团队可能会生成一体化,严密耦合的代码,但一些较小的团队可能会生成更独立、松懈耦合的代码(有关此相关性的更多信息,请参阅《Demystifying Conway’s Law》)。关于我们来说,这意味着我们的通讯结构不只影响特定的代码段,也影响整个代码库。因而,与原作者亲近沟通肯定是一个好办法,但我们应该自检不要太过于依赖于原作者。这不只可能会惹恼原作者,还可能在我们的代码中发生无意识的耦合。
尽管这有助于我们深入研讨代码,但这是在假定能够触摸原作者的状况下。在许多时分,原作者可能现已脱离了公司,或恰巧不在公司(例如正在度假)。在此种状况下我们该做什么?问询可能对代码有所了解的人。这个人纷歧定要曾真实作业于代码,他能够是在原作者编写代码时就在周围,也能够是知道原作者。哪怕仅是从原开发者周围的人中得到只言片语,也可能会启迪其他不知道的代码片段。
3.删去一切正告
心思学中有一个众所周知的概念,称为“破窗理论”,Andrew Hunt和Dave Thomas在《 The Pragmatic Programmer 》(第4-6页)中详细描绘了这个概念。这个理论开端是由James Q.Wilson和George L. Kelling提出的,描绘如下:
假定有一个建筑物有几扇破了的窗户。如果窗户没有修好,那么损坏者会趋向于打破更多的窗户。终究,他们乃至可能会破门而入,如果建筑物是没人住的,那么他们可能会非法占有或许在里面焚烧。也能够考虑人行道的状况。如果道路上面有废物堆积,那么不久之后,就会有更多的废物累积。终究,人们乃至会开端往那里扔外卖废物,乃至打破轿车。
这个理论指出,如果好像现已没人关怀这个物品或事物,那么我们就会忽视对物品或事物的照料,这是人的天分。例如,如果一栋建筑物看上去现已凌乱不堪,那么它更有可能被任意损坏。在软件方面,这个理论意味着如果开发人员发现代码现已是一团糟,那么人的赋性会让他弄坏代码。从实质上说,我们心里想的是(即便心思活动没有这么丰厚),“已然终究一个人不在乎这代码,我为什么要在乎?”或“都是乱糟糟的代码,谁知道是谁写的。”
可是,这不应该成为我们的托言。只需我们触摸曾经归于其他人的代码,那么我们就要对这些代码担任,而且如果它不能有用作业的话,我们得背负结果。为了打败这种人的天分行为,我们需求采纳一些小办法以防止我们的代码更少地被弄脏(及时替换破掉的窗户)。
一个简略办法是删去来自我们正在运用的整个包或模块中的一切正告。至于未运用或增加注释的代码,删去它。如果我们稍后需求这部分代码,那么在存储库中,我们总是能够从从前的提交中检索它。如果存在无法直接处理的正告(例如原始类型正告),那么运用@SuppressWarnings注解注释该调用或办法。这样能够保证我们对代码进行过细心的考虑:它们不是由于疏忽而宣布的正告,而是我们明确地留意到了正告(如原始类型)。
一旦我们删去或明确地制止一切正告,那么我们就有必要保证代码坚持革除正告。这有两个首要效果:
迫使我们细心考虑我们创立的任何代码。
削减代码糜烂的改动,现在的正告会导致今后的过错。
这对其他人,以及我们自己都有心思暗示效果——我们其实关怀我们正在处理的代码。它不再是条单行线——我们强逼着自己更改代码,提交,然后永不回头。相反,我们知道到我们需求对这代码担任。这对之后的软件开发也是有协助的——它向将来的开发人员展现,这不是一间窗户都破了的库房:而是一个保护杰出的代码库。
4.重构
在曩昔几十年中,重构现已成为了一个十分重要的术语,而且最近被当作是对当时作业代码做任何改动的代名词。尽管重构的确触及对当时正在作业的代码的更改,但并非整个全局。Martin Fowler在他关于这个论题的重要着作——《Refactoring》一书中将重构界说为:
对软件的内部结构进行更改,使其更简略了解而且修正起来更廉价,而不改动其可调查的行为。
这个界说的关键在于它触及的更改不会改动体系可调查的行为。这意味着当我们重构代码时,我们有必要要有办法来保证代码的外部可见行为不会改动。在我们的比如中,这意味着是在我们承继或自己开发的测验套件中。为了保证我们没有改动体系的外部行为,每逢我们进行改动时,都有必要从头编译和履行我们的悉数测验。
此外,并不是我们所做的每一个改动都被认为是重构。例如,重命名办法以更好地反映其预期用处是重构,但增加新功用不是。为了看到重构的长处,我们将重构SuccessfulFilter。履行的第一个重构是提取办法,以更好地封装个人净工资的逻辑:
在我们进行这种改动之后,我们从头编译并运转我们的测验套件,测验套件将持续经过。现在更简略看出,成功是经过一个人的年纪和净薪酬界说的,可是getNetSalary办法好像并不像Person类一样归于SuccessfulFilter(指示标志就是该办法的仅有参数是Person,该办法的仅有调用是Person类的办法,因而对Person类有很强的亲和力)。 为了更好地定位这个办法,我们履行一个Move办法将其移动到Person类:
为了进一步整理此代码,我们对每个magic number履行符号常量替换magic number行为。为了知道这些值的意义,我们可能得和原作者沟通,或许向具有满足范畴常识的人讨教,以引领正确的方向。我们还将履行更多的提取办法重构,以保证现有的办法尽可能简略。
从头编译和测验,发现体系依然依照预期的办法作业:我们没有改动外部行为,可是我们改进了代码的可靠性和内部结构。有关更杂乱的重构和重构进程,请参阅Martin Fowler的Refactoring Guru网站。
5.当你脱离的时分,代码比你发现它的时分更好
终究这个技能在概念上十分简略,但在实践中很困难:让代码比你发现它的时分更好。当我们整理代码,特别是他人的代码时,我们大多会增加功用,测验它,然后前行,不关怀我们会不会奉献软件腐朽,也不在乎我们增加到类的新办法会不会导致额定的紊乱。因而,本文的悉数内容可总结为以下规矩:
每逢我们修正代码时,请保证当你脱离的时分,代码比你发现它的时分更好。
前面提到过,我们需求对类形成的损坏和对改动的代码担任,如果它不能作业,那么修正是我们的责任。为了打败随同软件出产而呈现的熵,我们有必要强制自己做到脱离时的代码比我们发现它的时分更佳。为了不躲避这个问题,我们有必要归还技能债款,保证下一个触摸代码的人不需求再付出代价。说不定,将来可能是我们自己感谢自己这个时分的坚持呢。