百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文
读整理优先:小改进,大回报,整洁代码设计指南(下)

读整理优先:小改进,大回报,整洁代码设计指南(下)

  • 网站名称:读整理优先:小改进,大回报,整洁代码设计指南(下)
  • 网站分类:技术文章
  • 收录时间:2025-07-25 16:25
  • 网站地址:

进入网站

“读整理优先:小改进,大回报,整洁代码设计指南(下)” 网站介绍

1. 管理

1.1. 整理是软件设计的一部分,它涉及你、你与代码的关系,以及你与自己的关系

1.2. 即使在重构变得可行的今天,编程环境仍然缺乏重构的自动化支持

1.3. 单独整理

  • 1.3.1. 整理工作总得有个去处,不然还不如不整理
  • 1.3.2. 理工作放在单独的PR里,每个PR包含的整理工作越少越好
  • 1.3.3. 学习整理的人总是要经历一些必然的阶段
    • 1.3.3.1. 在第一个阶段,我们就是做修改,大量的修改,不会差别对待这些修改
    • 1.3.3.2. 把语句分成小段,就会容易形成解释型辅助函数(explaining helper),从而使修改行为也变得容易了
  • 1.3.4. 审查的延迟时间是另一种动机
    • 1.3.4.1. 如果代码很快就能完成审查,就应当鼓励创建更多更小的PR
    • 1.3.4.2. 更有针对性的PR又会加快审查的速度
  • 1.3.5. 掌握了整理、小步快跑和绝对安全的工作之后,建议不要审查整理工作的PR
    • 1.3.5.1. 可以进一步减少审查的延迟时间,让整理工作的PR越来越小

1.4. 整理链

  • 1.4.1. 抑制整理的冲动也是一项关键的整理技巧
  • 1.4.2. 设置好卫述句,判断条件就可以转化为“解释型辅助函数”,或者提取成“解释型变量”
  • 1.4.3. 清除杂乱无章的无用代码,就可以按“阅读顺序”或“内聚顺序”排列剩下的代码了
  • 1.4.4. 如果把功能相同的代码写成一样,把功能不同的代码写成不一样,就可以精确地把相似的代码按“阅读顺序”分组
  • 1.4.5. 有了全新接口,就忍不住想用
  • 1.4.6. 阅读顺序确定之后,“对称归一”的机会可能就会出现
    • 1.4.6.1. 调整顺序之前,代码元素的间隔很远,不太容易发现其相似性
  • 1.4.7. 按照内聚顺序把元素放在一起,它们就会成为“提取子元素”的候选
  • 1.4.8. 每一条给解释型变量赋值的语句,右半部分都可以作为一个“解释型辅助函数”
  • 1.4.9. 提取解释型常量会让代码呈现出“内聚顺序”
    • 1.4.9.1. 把一起修改的常量放在一起,未来改起来也更简单一些
  • 1.4.10. 将参数显式化之后,一些参数就可以组合成一个对象,而一些代码也可以移动到这个对象里
  • 1.4.11. 每个语句块之前都可以加上“解释型注释”
    • 1.4.11.1. 一个语句块可以提取成一个“解释型辅助函数”
  • 1.4.12. 提取出一个辅助函数之后,就可以引入“卫述句”、提取“解释型常量”和“解释型变量”,或者“删除多余注释”
  • 1.4.13. 把零碎的代码集中成混乱的代码块之后,我们希望通过“语句分块”、添加“解释型注释”,以及“提取辅助函数”来进行整理
  • 1.4.14. 通过引入“解释型变量”“解释型常量”或“解释型辅助函数”,尽可能把注释当中的信息移到代码里
  • 1.4.15. 消除冗余注释的噪声有助于更好地发现“阅读顺序”,或者发现“显式化参数”的机会
  • 1.4.16. 软件开发的主要成本消耗在变更上,而变更带来的成本主要是理解代码,因此,沟通代码的结构和意图是你可以锻炼的有价值的技能之一
  • 1.4.17. 注释是沟通的一种形式,但整理可以让你探索通过其他编程元素进行沟通的极限
    • 1.4.17.1. 只有绝对、完全多余的注释才应该删除
  • 1.4.18. 整理工作开始被整合到一起,实现对代码结构更大的更改
    • 1.4.18.1. 要警惕改得过多、过快
    • 1.4.18.2. 与一系列成功的代码整理相比,一次失败就要付出高昂的代价

1.5. 批大小

  • 1.5.1. 冲突
    • 1.5.1.1. 放在一批的整理工作越多,集成的延迟时间就越长,这样整理工作与别人正在做的工作发生冲突的概率也就越大
    • 1.5.1.2. 一旦遇到合并冲突,合并工作的成本就会上升一个数量级
  • 1.5.2. 交互
    • 1.5.2.1. 放在一批的整理工作越多,意外改变行为的可能性也会越高
    • 1.5.2.2. 当整理工作和行为修改发生交互时,合并成本也会大幅上升
  • 1.5.3. 投机
    • 1.5.3.1. 整理工作只要刚好能够支持下一次行为修改就可以
    • 1.5.3.2. 每一批的整理工作越多,就越容易只为了整理而整理,从而产生额外的成本
  • 1.5.4. 你和团队需要弄清楚,究竟如何才能降低审查成本
    • 1.5.4.1. 在信任和文化氛围浓厚的团队中,整理工作不需要审查
    • 1.5.4.2. 交互的风险已经大大降低,整理工作不经过审查也不会破坏软件的稳定性
    • 1.5.4.3. 要达到这种可以不用审查整理工作的安全和信任程度,需要几个月的时间

1.6. 节奏

  • 1.6.1. 整理是为了让未来对系统的行为修改变得更容易,这件事值得去做
  • 1.6.2. 管理整理工作的节奏也是一种管理整理工作的艺术
  • 1.6.3. 软件设计是分形的,可以层层分解,因此时间比例也可以任意缩放
  • 1.6.4. 行为修改往往会在代码里集中出现
    • 1.6.4.1. 据帕累托法则,80%的修改会发生在20%的文件中
    • 1.6.4.2. 优先整理的好处之一是整理也会集中出现,而且出现的地方正好就是在那些需要修改行为的地方
    • 1.6.4.3. 即使一开始你整理过了头,也没有关系
    • 1.6.4.3.1. 很快你就会发现自己想修改行为的代码已经整理好了
    • 1.6.4.3.2. 继续整理,大多数修改就发生在整理过的代码区域里
    • 1.6.4.3.3. 整理工作只需要几分钟到一小时

1.7. 解开乱麻

  • 1.7.1. 你正在修改某些代码的行为,然后发现做某项整理能让修改变得更容易
  • 1.7.2. 先要发现乱麻才能解开乱麻
    • 1.7.2.1. 乱麻发现得越早,解开的工作量就越少

1.8. 整理工作能让未来对系统行为的修改变得更容易

  • 1.8.1. 整理全部调用点并不是毫无意义的瞎折腾
  • 1.8.2. 一旦所有修改全部迁移完,总会有某种修改的成本降低
  • 1.8.3. 整理代码是一种很好的方法,能够让你意识到设计带来的详细结果
  • 1.8.4. 同一区域的行为还会被修改,而且很快就会修改
  • 1.8.5. 现在整理成本更低
  • 1.8.6. 整理的成本和修改行为的成本大致相当

1.9. 从不整理

  • 1.9.1. 这些代码再也不用修改了
  • 1.9.2. 改进设计也没什么好处,学不到东西

1.10. 以后整理

  • 1.10.1. 有一大堆整理工作等着要做,却没有立竿见影的效果
  • 1.10.2. 完成整理工作终会有回报
  • 1.10.3. 完成整理工作终会有回报

1.11. 事后整理

  • 1.11.1. 等到下次再整理,成本会更高
  • 1.11.2. 如果不整理,修改就好像没做完

1.12. 优先整理

  • 1.12.1. 马上可以见效,要么是理解更清楚了,要么是修改更容易了
  • 1.12.2. 你知道什么该整理,该怎么整理
  • 1.12.3. 优先整理是更好的选择,但不要为了整理而整理

2. 理论

2.1. 元素有边界,所以你知道元素从哪里开始到哪里结束

  • 2.1.1. 元素包含子元素

2.2. 软件设计中的关联

  • 2.2.1. 调用
  • 2.2.2. 发布
  • 2.2.3. 监听
  • 2.2.4. 引用

2.3. 进行软件设计时,是在机器指令和整个程序之间创建中间元素,这些中间元素就会互相作用带来收益

2.4. 软件有两种创造价值的方式

  • 2.4.1. 软件现在能做的事
  • 2.4.2. 未来可以让软件做新的事情

2.5. 期权性(optionality)

  • 2.5.1. 环境越不稳定,期权就越有价值,这是期权最大的优势之一
  • 2.5.2. 导致软件中的期权价值下降的情况
    • 2.5.2.1. 关键员工离职
    • 2.5.2.2. 和客户疏远
    • 2.5.2.3. 修改成本飙升

2.6. 系统结构对系统行为没什么影响

2.7. 软件设计是一种兼顾“赚得早花得晚”和“创造期权而非物品”的方式

2.8. 软件设计是为改变(行为)而做的准备

  • 2.8.1. 从期权性的角度思考软件设计
    • 2.8.1.1. 潜在的行为修改价值波动越大越好
    • 2.8.1.2. 开发的时间越长越好
    • 2.8.1.3. 未来的开发成本越低越好
    • 2.8.1.4. 创造期权的设计工作越少越好

2.9. 知道什么时候设计、怎么设计,以及什么时候不该设计

2.10. 结构修改通常是可逆的

  • 2.10.1. 不可逆决策的审查、双重检查、三重检查是非常重要的
  • 2.10.2. 代码审查流程没有区分可逆修改和不可逆修改
  • 2.10.3. 可逆的设计决策变为不可逆的另一种情况是,设计决策会在整个代码库中传播

2.11. 耦合

  • 2.11.1. 分析耦合并不能仅仅通过查看程序的源代码
  • 2.11.2. 更大的问题是级联变化
    • 2.11.2.1. 变化的成本遵循幂律分布,这种分布是由级联变化的成本造成的
    • 2.11.2.2. 幂律分布的一个特点是少数几个大的“离群事件”非常重要
  • 2.11.3. 要降低软件成本,必须减少耦合
    • 2.11.3.1. 解耦并不是免费的,需要权衡利弊
  • 2.11.4. 耦合就像黑夜里的乐高积木,只有踩到才能感觉到
  • 2.11.5. 为了更早获得收入就会导致耦合
  • 2.11.6. 基本的决策空间依然存在
    • 2.11.6.1. 可以承担耦合的成本,也可以承担解耦的成本

2.12. 内聚

  • 2.12.1. 耦合的元素应该是拥有共同包含元素的子元素
  • 2.12.2. 将耦合的元素捆绑到它们自己的子元素中
  • 2.12.3. 将不耦合的元素放到其他地方
    • 2.12.3.1. 耦合的元素应该是拥有共同包含元素的子元素
    • 2.12.3.2. 将耦合的元素捆绑到它们自己的子元素中
  • 2.12.4. 不要大幅度地重新排列所有元素

2.13. 对于所有人来说,不要过于超前规划,但你正在学习的这种精妙绝伦的技术,其最终回报是与他人能更好地相处