重构三部曲(一):思想准备篇

一、概述

重构三部曲为:思想准备,单元测试,重构

  • 思想准备的目的是明确:为什么要重构,重构的理论支撑是什么
  • 单元测试:重构依托于良好的测试,单元测试是保证重构顺利进行的神兵利器
  • 重构:依照《重构》中的重构技巧进行实战

本文主要是摘录自《重构 改善既有代码设计》的原话,有一部分是个人对原文的个人理解。

重构的思想并不是只适用于重构,也适用于开发过程中的代码编写,两者的目的都是写出良好的代码。

光知道还不够,还必须付诸应用;光有决心还不够,还必须行动

二、代码需要意图明显

  • 重构的定义:在不改变软件可观察行为的前提下改善其内部结构
  • 重构的意义在于:你永远不必说对不起--只要把出问题的地方修补好就行了。(“封装”不可能永远都是适用的,可能过一段时间之前很完美的封装就会显得很“臃肿”了)
  • 你的代码首先是为人写的,其次才是为计算机写的,写出人类容易理解的代码
  • “封装”意味着每个对象都应该尽可能少了解系统的其他部分
  • 关键不在于函数的长度,而在于函数“做什么”和“如何做”之间的语义距离
    • 代码用途和实现手法之间的语义距离
    • 意图要明确,明确说出我所需要的。
    • 提高代码的可理解性,降低其修改成本
    • 避免“代码传达的信息与你的意图南辕北辙”
  • 需要为代码编写文档意味着代码本身写的不好
  • 函数的名称应该准确表达它的用途
  • 好的代码,更有利于性能的优化(不要因为性能而牺牲代码的清晰性)

三、重构要小步前进

  • 重构依托于良好的单元测试。
    • “重构需要一组可靠的测试环境”
    • 测试应该是一种风险驱动行为
  • 一定要快速前进,快速失败并更正,然后再重复
    • 重构应该小步前进,比如修改一个局部变量或者提炼一个函数
    • 每一步出现异常都应该回滚上个版本,保证输出不变
  • 设计模式为重构提供了目标
  • 你之所以进行重构,必定是为了达到某个目的,而不仅仅是为了看起来有所动作
  • 大型重构耗费是假长,在这个过程中,你应该根据需要安排自己的工作,只在需要添加新功能或修补错误时擦进行重构。重构程度只要能满足其他任务的需要就行了
  • 应对并处理变化,是软件开发的根本复杂性之一
  • 重构时不应该有任何添加功能的操作,重构是对已有功能的操作,必须保证软件可观察方式(输出)是不变的。
  • 哪怕你完全了解系统,也请实际度量它的性能,不要臆测。臆测会让你学到一些东西,但十有八九你是错的。
  • 你必须培养出自己的判断力
  • 问题发现的越早,为修复而付出的代价越低。

四、重构方法的一些摘录

  • 一个类应该是一个清楚的抽象,处理一些明确的责任
    • 决定把责任放在哪儿
    • 分解类所负的责任,分解出新类的旧类如果责任与名称不符,进行更名
  • 间接性可能带来帮助,但非必要的间接性总是让人不舒服
  • 观察类应该做的所有事情,然后针对任何一项功能的任何一种可能失败情况
  • 增加子类的目的,是为了增加新特性或变化其行为
  • 如果某个类在不同环境下扮演截然不同的角色,使用接口就是个好主意
  • 绝大多数情况下,函数应该放在它所使用的数据的所属对象内
  • 将复杂的处理过程分解成小函数
    • 先搬离低层函数,再搬离高层函数
    • 将查询函数和修改函数分离
  • 所谓重构继承体系,往往是将函数和字段在体系上下移动
  • 如果你手上没有所需的东西,总可以叫另一个对象给你
  • 在分布式软件中,函数的往返必须被减至最低限度
  • 任何有返回值的函数,都不应该有看得到的副作用
  • 所有的数据都应该隐藏起来
    • 数据隐藏,你绝不应该将数据声明为public
    • 哑数据对象--除数据访问函数外,没有其它任何函数
  • 程序当中,复杂的条件逻辑是最常导致复杂度上升的地点之一
    • ”分支逻辑“和”操作细节“分开
  • 加入断言,永远不会影响程序的行为。
    • 不要滥用断言
    • 更多的时候,断言的价值在于:帮助程序员理解代码正确运行的必要条件
  • 过长的参数列总是难以理解的
    • 如果有必要,将参数的计算过程提炼到一个独立函数中
    • 应该只在必要关头才添加参数,预先添加的参数很可能并不是你所需要的。
  • 重复代码是系统中最糟糕的东西之一
    • 避免行为重复,因为这容易导致 ”修改一个却未能修改另一个“的风险

你可能感兴趣的:(重构三部曲(一):思想准备篇)