【原创】回首依然灿烂

重构——改善既来代码的统筹
Refactoring——Improve the Design of Existing Code
作者: 马丁 富勒Martin Fowler

回顾,使自身懂了强调;使自己感触了采暖;使自身掌握了情味;是自了解了追求的义;使自己想到了存在的真理。

同、什么是重构?

所谓重构举凡这么一个过程当匪移代码外在表现的前提下,对代码作出修改,以精益求精程序的内部结构。本质上说,重构就是在代码写好之后改进其的设计

重构(名词):本着软件内部结构的一致种植调动,目的是于匪改变软件而观察行为的前提下,提高该可理解性,降低该修改成本
重构(动词):动同一雨后春笋重构手法,在匪转软件可察行为之前提下,调整其布局

重构的目的是一经软件还爱给清楚与改动。重构切莫会见转移软件可观察的行——重构之后软件功能仍。

重构技术就是是因细微的步履修改程序,如果您发下错,很易就可发现其。


昨一个学生满眼美溢着圈在自:老师,你记得你说了千篇一律句很美之口舌也?

十一、简化函数调用

  1. 函数改名(Rename
    Method)。函数的称谓不能揭示函数的用处。修改函数的名。
  2. 累加参数(Add
    Parameter)。某个函数需要由调用端得到重新多信息。为是函数添加一个对象参数,让该目标带来进函数所待信息。
  3. 移除参数(Remove
    Parameter)。函数本体不再要有参数。将拖欠参数去除。
  4. 将查询函数和改动函数分离(Separate Query from
    Modifier)。某个函数既归对象状态值,又涂改对象状态。建立两单例外的函数,其中一个顶查询,另一个当修改。
  5. 让函数携带参数(Parameterize
    Method)。若干函数做了接近的行事,但当函数本体中倒蕴涵了不同的价。建立单一函数,以参数表达那些不同的价值。
  6. 因为强烈函数取代参数(Replace Parameter with Explicit
    Methods)。你产生一个函数,其中完全在参数值而采用两样行为。针对该参数的各个一个或价值,建立一个单独函数。
  7. 保对象完整(Preserve Whole
    Object)。你从某对象被取出若干值,将她当做某平等不良函数调用时之参数。改也传送整个对象。
  8. 为函数取代参数(Replace Parameter with
    Methods)。对象调用某个函数,并以所得结果作为参数,传递给其它一个函数。而接受该参数的函数本身吗克调用前一个函数。让参数接受者去除该项参数,并直调用前一个函数。
  9. 引入参数对象(Introduce Parameter
    Object)。某些参数总是很当然地而起。以一个对象取代这些参数。
  10. 移除设值函数(Remove Setting
    Method)。类吃之某字段应该于目标创建时给设值,然后便不再改变。去丢该字段的持有设值函数。
  11. 隐藏函数(Hide
    Method)。有一个函数,从来没让另外任何类用到。将这函数修改为private。
  12. 为工厂函数取代构造函数(Replace Constructor with Factory
    Method)。你要以创建对象时不只是做简单的构建动作。将构建函数替换为工厂函数。
  13. 包裹向下转型(Encapsulate
    Downcast)。某个函数返回的目标,需要由函数调用者履于下转型。将向下转型动作变到函数中。
  14. 因非常取代错误码(Replace Error Code with
    Exception)。某个函数返回一个一定的代码,用以代表某种错误情况。改用异常。
  15. 盖测试取代异常(Replace Exception with
    Test)。面对一个调用者可以先检查的标准,你扔来了一个可怜。修改调用者,使它在调用函数之前先行做检查。

初中阶段是亲骨肉终身里连小学送于高中的一样截青葱年少之较波折的程,在此等级就课业的强化,和自我意识的慢慢觉醒,渐渐有了整个得我做主的定能力,也时有发生一部分孩子因成长环境影响,原生家庭里种的问题等等,孩子开始上叛逆、分化的流,工作面临之零碎,重复甚或乱还见面给导师自己乱了轻微。这亟需多多大耐力及静守,等他们顺利的走过梗起脖颈回首看到教师宽容的笑颜……那是为此时堆砌起的易跟指引。过了过多年,回到母校来瞧我们的,这些调皮捣蛋的学童重重,他们跟老师的熟络、默契、亲昵甚至你碰巧端起茶杯他见面即刻填满你的茶水,那是代了有点多少去之千言万语呀……因此,我及她们说,我比其他人幸运,我之干活是:等待花开的日子,又浪漫而辛苦又美!

十四、经典句子

  1. Any fool can write code that a computer can understand. Good
    programmers write code that humans can understand.
    ——Martin
    Fowler

    另一个白痴都能够写有计算机可以领略的代码。唯有写来人类容易了解的代码,才是上好之代码。
    ——Martin Fowler
  2. I'm not a great programmer; I'm just a good programmer with
    great habits.
    ——Kent Beck
    我未是个光辉之程序员,我只是一个装有一些良好习惯的好程序员。
    ——Kent Beck
  3. Computer Science is the discipline that believes all problems
    can be solved with one more layer of indirection.
    ——Dennis
    DeBruler

    微机对是这般平等帮派科学:它相信有题目且足以通过增加一个间接层来解决。——Dennis
    DeBruler

图片 1


各国一个昨天且是财物,每一个明都是要。我庆幸自己爱回首,我道谢我永远有梦想的心头,不失争辩或厚或淡。

次、为何重构?

(1)
重构改进软件设计。如果没有重构,程序的计划性会日益堕落变质。重构很像是于重整代码,你所做的尽管是于所有东西回到应出的职位上。经常性的重构可以拉维持友好该有的样子。

(2)重构使软件还便于掌握。重构可以扶持我们吃代码更易读。

(3)重构帮助找到bug。对代码进行重构,可以协助我们深入了解代码,对代码理解的愈发老,就越会拉咱找到bug。重构能够帮助我们还管用地描绘有健康的代码。

(4)重构提高成为速度。重构可以帮助我们再快捷地开发软件,因为其阻挡系统腐败变质,它还是还得提高设计质量。


“我之办事就是是:等待花开的生活”

十二、处理包括关系

  1. 字段上转移(Pull Up
    Field)。两只子类拥有同样之字段。将拖欠字段移至超类。
  2. 函数上转移(Pull Up
    Method)。有些函数,在一一子类中发出完全相同的结果。将该函数易至超类。
  3. 构造函数本体上转移(Pull Up Constructor
    Body)。你于依次子类中负有一些构造函数,他们的本体几乎完全一致。在超类中初修一个构造函数,并以子类构造函数中调用它。
  4. 函数下换(Push Down
    Method)。超类中之有函数只与局部(而未全部)子类有关。将之函数移到有关的那些子类去。
  5. 许段下更换(Push Down
    Field)。超类中的某某字段只于有些(而未全部)子类用到。将之字段移到得它们的那些子类去。
  6. 提炼子类(Extract
    Subclass)。类吃的一些特征只为某些(而休全部)实例用到。新建一个子类,将方面所说之那有些表征移到子类中。
  7. 提炼超类(Extract
    Superclass)。两单近乎有类同特性。为就半只类似建立一个超类,将平特性移至超类。
  8. 提炼接口(Extract
    Interface)。若干客户利用类接口中的同一子集,或者简单独八九不离十的接口有一部分同样。将一律的子集提炼到一个单身接口中。
  9. 折叠继承体系(Collapse
    Hierarchy)。超类和子类之间无极端可怜差别。将它合为一体。
  10. 造模板函数(Form TemPlate
    Method)。你产生部分子类,其中相应的一点函数以同顺序执行类似的操作,但各个操作的底细及独具不同。将这些操作分别放上独立函数中,并保障其都有一致的签字,于是原函数为即变换得千篇一律了。然后以原本函数上更换至超类。
  11. 以信托代继承(Replace Inheritance with
    Delegation)。某个子类只使用超类接口中之同一片,或是根本未欲持续而来之数据。在子类中初砌一个字段用以保存超类;调整子类函数令它改变而委托超类;然后去丢两者之间的接轨关系。
  12. 因为持续取代委托(Replace Delegation with
    Inheritance)。你于片只类似中用委托关系,并时不时也整个接口编写许多极度简的托函数。让委托类来就承受托类。

回首能使自身痛快地笑,痛快地哭,幽幽地唉声叹气,寂寂地发呆。然后尽情的发扬起笑靥,坚强的企起口角,轻咬嘴唇,给自己一次次更风雨洗礼的机会,找寻一朵朵属自己的通向阳花。

自身之经验:

  1. 读者最有必然之档次阅,或者了解了局部代码风格、设计模式、代码设计哲学等。
  2. 当下是同样仍以java语言来讲重构的开,读者最好理解面向对象的基本知识,了解java、C++等面向对象的言语。
  3. 自莫是作java开发之,但是自打听面向对象,了解C++,java。书被之一部分驳斥以及指导在其它计划语言及吧出大怪之鼎力相助,并且我发觉,在路面临我此时便在动用在有些重构方法。书被那些过于结合面向对象的包装、继承、多态等文化之重构方法,可能就是特适用于面向对象的语言吧。
  4. **汝值得一念。反复看,反复读。 **

乍一年温暖的春同时比方来临了。

其三、何时重构?

重构不是千篇一律宗理当特别扭出时间举行的事体,重构应该随时随地进行。不该为重构而重构,之所以重构,是坐我们怀念做别的呀事,而重构可以帮我们管那些事开好。

其三糟糕法虽:从事不了三,三则重构

(1)丰富职能时重构。
(2)修补错误时重构。
(3)复审代码时重构。


回顾逝去就几十年之各级一样天,依然让自己那样痴迷。

五、代码的坏味道

  • 再次代码(Duplicated Code)
  • 过长函数(Long Method)
  • 过特别之类似(Large Class)
  • 过长参数列(Long Parameter List)
  • 发散式变化(Divergent Change):一个类受多种扭转之影响
  • 霰弹式修改(Shotgun Surgery):一种变更引发多独八九不离十对应修改
  • 留恋情结(Feature Envy):函数对某类的兴高了自己所处类的兴趣
  • 数量泥团(Data
    Clumps):相同的好多起数据出现于不同地方,这些绑在一齐出现的多寡应发生属它们自己之靶子
  • 主干类型偏执(Private
    Obsession):很多人口非情愿以有些任务上利用小目标
  • switch惊悚现身(Switch
    Statements):switch语句会在群地方又出现,一改则需全改
  • 平继承体系(Parallel Inheritance
    Hierarchies):当你吧某个一个近乎增加子类时,也非得也其它一个接近对应增多一个接近
  • 冗赘类(Lazy Class):如果一个类不值得在,那便叫她消灭
  • 夸夸其谈的前程星辰(Speculative
    Generality):预留的废的抽象类,无用的空洞参数
  • 教人迷惑的暂时性字段(Temporary
    Field):类中有只字段只也一些特殊状况如果设置
  • 过火耦合的消息链(Message
    Chains):用户向一个靶要另一个靶,然后再向后者要另一个目标......
  • 中间人(Middle Man):无用的信托,过多的中间层
  • 性感关系(Inappropriate
    Intimacy):两单近乎过于接近,一个好像过于关注其他一个看似的成员
  • 如出一辙之近乎(Alternative Classes with Different
    Interfaces):不同名字的接近还是函数,作者相同之行
  • 未周到的库类(Incomplete Library Class):类库设计无可能到
  • 纯数据类(Data
    Class):一个好像具有一些字段以及用于访问这些字段的函数,除此之外一无长物
  • 被拒绝的遗赠(Refused
    Bequest):子类不思继承超类所有的函数和多少,只想挑几样来玩
  • 过多的注释(Comments)

追思,已不复是惨不忍睹心灵的流离失所。

季、何时休拖欠重构?

代码根本无法工作或极端不好,重构还不苟更写来的简短

当列之尾声时限,应该避免重构


包涵我年纪万分了,说过许多言,不理解您记忆的凡啊一样句?

十三、大型重构

  1. 梳理并说继承体系(Tease Apart
    Inheritance)。某个继承体系又承担两件责任。建立两只连续体系,并透过委托关系为内部一个方可调用另一个。
  2. 以过程化设计中转为对象设计(Convert Procedural Design to
    Objects)。你时有局部风俗过程化风格的代码。将数据记录变成对象,将大块的表现分成小片,并以作为易入有关对象中。
  3. 拿世界及发挥/显示分离(Separate Domain from
    Presentation)。某些GUI类之中包含了世界逻辑。将世界逻辑分离出来,为其建立单独的领域接近。
  4. 提炼继承体系(Extract
    Hierarchy)。你来某个号做了极多办事,其中一些干活是盖恢宏标准化表达式完成的。建立继续体系,以一个子类表示一致种新鲜状况。

回溯来程,发现那条年轻的轨道就力不从心辨别。我们受这世界与调谐留的,原来并无可以据此方便或特困来简单概括。我们连年来不及反省,来不及演绎,甚至来不及后悔,就都匆匆走了事了人生受到的同行程,走过了青春最妖媚的同样段落。

八、在对象期间搬移特性

  1. 搬迁移函数(Move
    Method)。你的次第中,有个函数和那个所驻之外的其余一个接近进行双重多交流:调用后者,或吃后人调用。在该函数最常引用的近乎吃成立一个负有相仿行为之初函数。将本来函数变成一个单纯的寄托函数,或是将原本函数完全移除。
  2. 搬迁移字段(Move
    Field)。你的次序中,某个字段被那所驻类之外的别样一个看似更多地用到。在对象类新建一个字段,修改来自字段的有着用户,令她改用新字段。
  3. 提炼类(Extract
    Class)。某只近乎做了应有产生零星只类似做的从事。建立一个新类,将相关的字段和函数从旧类搬移到新类。
  4. 以看似内联化(Inline
    Class)。某个类没有开尽多事情。将以此看似的备特性搬移到外一个好像中,然后移除原类。
  5. 躲藏“委托关系”(Hide
    Delegate)。客户通过一个寄托来调用另一个靶。在劳务类及树立客户所需要的有函数,用以隐藏委托关系。
  6. 移除中间人(Remove Middle
    Man)。某只类似做了过多的简委托动作。让客户直接调用受托类。
  7. 引入外加函数(Introduce Foreign
    Method)。你用也提供劳动之类似增加一个函数,但您无法修改是仿佛。在客户类中建立一个函数,并因为率先参数形式传播一个服务类实例。
  8. 引入本地扩展(Introduce Local
    Extension)。你需要为服务类提供有格外函数,但若无法修改是近乎。建立一个新类,使它含这些额外函数。让这扩展品成为源类的子类或包装类。

回首,已不复是永远失败的表象。

九、重新组织数据

  1. 于封装字段(Self Encapsulate
    Field)。你一直访问一个字段,但和字段之间的耦合关系日趋变得笨拙。为夫字段建立取值/设值函数,并且只是因为这些函数来访问字段。
  2. 因目标取代数据值(Replace Data Value with
    Object)。你来一个数据项,需要跟任何数与行同下才发含义。将数据项改成对象。
  3. 将价值对象改也援对象(Change Value to
    Reference)。你打一个接近衍生出累累彼此相当的实例,希望以它替换为和一个目标。将这价对象变成引用对象。
  4. 将引用对象改吗价值对象(Change Reference to
    Value)。你闹一个引用对象,很粗且不可变,而且对管理。将其化一个值对象。
  5. 因为目标取代数据(Replace Array with
    Object)。你生一个数组,其中的因素分别代表不同之东西。以目标替换数组,对于数组中的每个元素,以一个字段来代表。
  6. 复制“被监视数据”(Duplicate Observed
    Data)。你生出一些领域数据在GUI控件被,而世界函数需要看这些多少。将拖欠多少复制到一个世界对象吃。建立一个Observe模式,用以同步领域对象以及GUI对象内之双重数据。
  7. 拿只为关系改吧双向关联(Change Unidirectional Association to
    Bidirectional)。两只类似都用用对方特性,但中只生一样久才为链接。添加一个反向指针,并要修改函数能够又创新两长长的链接。
  8. 拿双向关联改也特为关系(Change Bidirectional Association to
    Unidirectional)。两只类似里时有发生双向关联,但其中一个看似如今不再要任何一个像样的特性。去除不必要的关系。
  9. 以字面常量取代魔法数(Replace Magic Number with Symbolic
    Constant)。你产生一个字面数价,带有特别意义。创造一个常量,根据该意思为其命名,并以上述的字面数值替换为者常量。
  10. 封装字段(Encapsulate
    Field)。你的切近吃在一个public字段。将它们声明也private,并提供相应的走访函数。
  11. 打包集合(Encapsulate
    Collection)。有个函数返回一个集聚。让这个函数返回该集的一个单独念副本,并当斯类似吃提供丰富/移除集合元素的函数。
  12. 坐数据类取代记录(Replace Record with Data
    Class)。你用直面传统编程环境被的记录组织。为该记录创建一个“哑”数据对象。
  13. 坐看似取代类型码(Replace Type Code with
    Class)。类中有一个数值类行码,但其并无影响类的一言一行。以一个新的好像替换该数值类型码。
  14. 盖子类取代类型码(Replace Type Code with
    Subclass)。你同时一个不可变的类型码,它见面影响类的行。以子类取代这个类型码。
  15. 坐State/Strategy取代类型码(Replace Type Code with
    State/Strategy)。你产生一个类型码,它会潜移默化类的行事,但若无法通过持续手法消除其。以状态对象取代类型码。
  16. 坐字段取代子类(Replace Subclass with
    Fields)。你的逐条子类的唯一差别就在“返回常量数据”的函数身上。修改这些函数,使他么返回超类中的之一(新增)字段,然后销毁子类。

全班同学都笑洋洋地看正在自己……教室里荡漾着淡淡的日光,我不由得笑起来了。

六、构筑测试网

  1. 重构的首要前提是有一个保险的测试环境
  2. 假使写好一点效果,就顿时添加测试,并包所有测试都完全自动化,让它检查自己之测试结果。一学测试就是一个强的bug侦测器,能够大大压缩查找bug所待的辰。
  3. 著测试代码的最好得力时机是当开始编程之前。当你待添加特性的当儿,先勾勒相应测试代码。编写测试代码其实就是在发问自己:添加这个效果要开来什么。编写测试代码还会而你管注意力集中让接口而休实现。预先写好的测试代码也为公的干活设置一个鲜明的结束标志:一旦测试代码正常运转,工作就好收了。
  4. 差不多用单元测试。测试你尽担心失误的地方,考虑或者出错的分界条件。不要因为测试无法捕捉所有bug就未写测试,因为测试的确可以捕捉到大多数bug。“花合理时间抓来大多数bug”要好了“穷尽一生抓来有bug”。

转首回望,真实的日光依旧挂于天空,美丽的彩云五彩而灿烂。

十、简化条件表达式

  1. 说条件表达式(Decompose
    Conditional)。你发一个错综复杂的口径(if-then-else)语句。从if、then、else三划分段落中分头提炼出单身函数。
  2. 合条件表达式(Consolidate Conditional
    Expression)。你有一样多样标准测试,都拿走同结果。将这些测试合并为一个规则表达式,并将以此法表达式提炼成为一个独自函数。
  3. 合并重复的条件有(Consolidate Duplicate Conditional
    Fragments)。在法表达式的每个分支上存有同样的一致截代码。将随即段还的代码搬移到条件表达式之外。
  4. 移除控制标记(Remove Control
    Flag)。在同样名目繁多布尔表达式中,某个变量带有“控制标记”的意向。以break语句或return语词取代控制标记。
  5. 以卫语句取代嵌套条件表达式(Replace nested Conditional with
    Guard
    Clauses)。函数中的条件逻辑使人头为难判断正常的推行路径。使用卫语句表现抱有的与众不同状况。
  6. 为多态取代条件表达式(Replace Conditional with
    Polymorphism)。你眼前有只标准表达式,它根据目标类型的例外取舍不同的行为。将此标准表达式的每个分支放上一个子类内的覆写函数中,然后以原始函数声明也架空函数。
  7. 引入Null对象(Introduce Null
    Object)。你得反复检查有目标是否也null。将null值替换为null对象。
  8. 引入断言(Introduce
    Assertion)。某平等段子代码用对先后状态做出某种假设。以断言明确表现这种如。

遂,我从没感叹人生易逝,功名难求;从不牢骚满腹,怨事尤人;我从不察观别人的脸色行事。洒脱而自在;自当以简单。

自身的胡说八道:

  1. 受你们发现了,其实自己耶是一个程序员,还是低档程序员。
  2. 随即按照书据说是java进阶必看,也是程序员必看之经典书籍。设计语言本身可能来分,造成一些特色也会见发出分别,但是一些思想还是相通之。所有,非java、C++语言工作者,也必然要是读一下。
  3. 据称stack
    overflow.com上登出之同一首《哪一样本书最富有影响力,是每个程序员都应有读的?》。《重构》这按照开就行前十,貌似是第六称。

重构——改变既出代码的设计.jpg


ps:我的笔记只记录了理论部分,书上每种重构方法都配有实例代码来讲解,大家可以细细研究。

初的平龙而开始了。

七、重新组织函数

  1. 提炼函数(Extract
    Method)。你有一样段代码可以叫组织在并并单独出来。将及时段代码放上一个独门函数中,并以函数名称解释该函数的用途。
  2. 内联函数(Inline
    Method)。一个函数的本体和名称相同清楚易亮。在函数调用点插入函数本体,然后换除了该函数。
  3. 内联临时变量(Inline
    Temp)。你产生一个现变量,只让一个略表达式赋值一差,而它们妨碍了别重构手法。将有对拖欠变量的援动作,替换为对其赋值的不行表达式自身。
  4. 以询问取代临时变量(Replace Temp with
    Query)。你的程序为一个现变量保存有同表达式的运算结果。将是表达式提炼到一个独函数中。将之临时变量的兼具引用点替换为对新函数的调用。此后,新函数就不过叫别函数使用。
  5. 引入解释性变量(Introduce Explaining
    Variable)。你发出一个扑朔迷离的表达式。将拖欠复杂表达式(或内部部分)的结果放上一个现变量,以此变量名称来解释表达式用途。
  6. 解释临时变量(Split Temporary
    Variable)。你的次来有临时变量被赋值过相同赖,它既非是循环变量,也非受用于采集计算结果。针对每次赋值,创造一个独、对应之临时变量。
  7. 移除对参数的赋值(Remove Assignments
    Parameters)。代码对一个参数进行赋值。以一个现变量取代参数的岗位。
  8. 为函数对象取代函数(Replace Method with Method
    Object)。你生一个巨型函数,其中对片变量的下如你无法使Extract
    Method。将是函数放上一个独对象被,如此一来局部变量就变成了靶内之字段。然后您可以当与一个对象吃以这巨型函数分解为多单小型函数。
  9. 替换算法(Substitute
    Algorithm)。你想使管有算法替换为外一个还鲜明的算法。将函数本体替换为任何一个算法。

当下可能是如出一辙种哲学,关于生命的哲学。然而,我并无连续失望,因为我自信自己连无总是缺乏才智和胆略。我的良心一直以跳,热血始终在燃烧。

不曾悟出,他们那么享受立同样词话!因了其的平等句话,让我立马半龙一直在回想,回首这几十年之风风雨雨的行途,回首来程,就给一行行失去的脚印在大脑的奥复活,一幕幕年青的剧重演,一幅幅人生之风景再现,其实这就是自家的成本。

图片 2

正是如此也。

早起从,心平如镜。留一点孤寂吃自己,做要好好的行,看自己爱的修,听好爱的讴歌,静静地等候着时间,怀揣在时间的之轻叹在诗行里行动摇摆。

相关文章

Comment ()
评论是一种美德,说点什么吧,否则我会恨你的。。。