0%

003-重构原则

摘要:

  • 何谓重构
  • 为何重构
  • 何时重构
  • 怎么对经理说
  • 重构的难题
  • 重构与设计
  • 重构与性能
  • 重构起源何处

概述

何为重构

  • 名词定义1:对软件内部结构的一种调整,目的是爱不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本
  • 动词定义:使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构

为何重构

  • 改进软件设计
  • 使软件更容易理解
  • 帮助找到Bug
  • 提高编程速度

何时重构

  • 三次法则:事不过三,三则重构
  • 添加功能时重构:帮助理解需要修改的代码,理清代码结构;新特性的添加会更快速、流畅
  • 修补错误:代码更具可读性;没清晰到让人一眼看出bug
  • 复审代码:开发团队中传播知识,传递经验,获得建议;和团队进行设计复审:UML示意图展示设计,CRC卡展示软件情节;和单个开发者进行代码复审

需要重构的代码

  • 难以阅读的
  • 逻辑重复的
  • 添加新行为使需要修改已有代码的
  • 带复杂逻辑条件的

目标

  • 易阅读
  • 易修改
  • 所有逻辑在唯一地点指定
  • 新的改动不会危机现有行为
  • 尽可能简单表达逻辑条件

间接层是一把双刃剑

  • 将大型对象拆成多个小型对象,将大型函数拆成多个小型函数
  • 缺点:一个东西分两份,增加管理难度;
    • 多个委托依次依赖,程序难以阅读
  • 优点:
    • 父类、子类:允许逻辑共享
    • 分开解释意图和实现
    • 隔离变化
    • 封装条件逻辑:多态消息

数据库

问题

  • 程序与数据库结构紧密耦合
  • 数据迁移:数据库结构改变
  • 数据库模型复杂,难以控制

    方案

  • 对象模型和数据库模型间插入一个分割层,隔离两个模型各自的变化。
    • 缺点:增加系统复杂性
    • 优点:带来很大的灵活性
  • 面向对象数据库:提供不同版本的对象间的自动迁移宫娥能

修改接口

  • 接口,修改要特别谨慎。一旦被修改,任何事情都有可能发生
  • 对象,可以允许分开修改软件模块的实现和接口,可以安全地修改对象内部实现而不影响他人
  • 影响:被“找不到,或找到不能修改”的代码使用,会成为问题。即,已发布的接口
  • 已发布的接口修改:旧接口调用新接口,并标记为deprecated
  • 尽量少发布接口,不要公开太多的接口。在强调代码所有权上做出适当让步
  • 发布接口有代价,除非真的有必要
  • 不要过早发布接口
  • 在throw子句中增加一个异常

何时不该重构

  • 代码太混乱,不如重写一个来的简单:代码无法正常运作,或无法稳定运作
  • 折中办法:“大块头软件”重构封装为良好的小型组件,逐一对组件做出“重构、重建”的决定
  • 项目接近最后期限,避免重构。为时已晚。
  • 重构确实可以提高生产力。如果最后没有足够的时间,通常表示应早该进行重构

重构与设计

  • 互补关系
  • 预先设计,避免返工成本
  • 重构改变了预先设计的角色,不必确保预先设计一定是正确无误的,只需要一个足够合理的解决方案即可
  • 重构让日后的修改成本不在高昂
  • 软件设计得以简化。足够灵活、可靠的解决方案,成本难以估算;所有可能变化的地点都建立灵活性,会使整个系统的复杂度大大提高;最后可能这些灵活性毫无必要
  • 重构是另一途径,来应付变化的风险。只需考虑:将一个简单的解决方案重构成一个灵活方案的难度?一般都“相当容易”
  • 重构:更简单的设计,不损失灵活性,降低设计过程的难度和压力

重构与性能

  • 不赞成为了提高设计的纯洁性而忽视性能,不将性能寄托在更快的硬件上
  • 重构,可能使软件运行更慢,也可使软件的性能优化更容易
  • 除了对性能有严格要求的实时系统,其他任何情况下“编写快速软件”的秘密就是:首先写出可调的软件,然后调整他以求获得足够的速度
  • 编写快速软件的方法:
  1. 时间预算法。
    • 多用于性能要求极高的实时系统。
    • 分解设计时做好预算,给每个组件预先分配一定的资源(包括时间和执行轨迹),每个组件绝对不能超过自己的预算,就算拥有组件之间调度预配时间的机制也不行。
    • 此方法,高度重视性能
  2. 持续关注法。
    • 要求任何程序员在任何时间做任何事,都设法保持系统的高性能
    • 通常没有太大作用,视角通常太狭隘。
    • 修改只是为了提高性能,通常会使程序难以维护,继而减缓开发速度
    • 一视同仁的优化所有代码。90%的优化都是白费劲,代码很少被执行,没达到应有的效果。需要对程序有清楚的认识
  3. 90%统计数据
    • 编写构造良好的程序,不能对性能投以特别的关注,直至进入性能优化阶段(通常在开发后期)
    • 首先,用一个度量工具来监控程序的运行,得到哪些地方消耗大量的时间、空间,找出性能热点所在的代码
    • 注意力集中在性能热点上,较少的工作量可得到较好的成果
    • 保持谨慎,应小幅度进行修改,每一步都需编译、测试、再次度量。如果性能没有提高,则撤销此次修改
    • 保持“发现热点,去除热点”,直至得到满意的性能
  • 构造良好的程序的帮助
  1. 较充裕的时间进行性能调整。构造良好的代码,可帮助更快速地添加功能,有更多的时间用在性能问题上(准确的度量则保证将时间投资在恰当的地方)
  2. 构造良好的程序,在性能分析时有更细的粒度。度量工具将你带到范围较小的程序段落中,性能调整更容易些。代码更加清晰,则帮助理解自己的选择,更清楚那些调整起关键作用。
  • 短期看,重构可能使软件变慢,但优化阶段的软件性能调整容易,最终更易得到较好的效果。

重构缘起何处

  • 优秀的程序员肯定至少会花一些时间来清理自己的代码。
  • 简洁的代码比杂乱无章的代码更容易修改
  • 知道自己几乎无法一开始就写出简洁的代码
  • 重构可以提高生产力,对于开发灵活高效的框架很有帮助
  • 重构使一门非常重要的技术,对生产性能、产品质量带来很大的影响
一分也是爱,两分情更浓【还没有人赞赏,支持一下呗】