HackerTube ?

RailsConf 2014 - All the Little Things by Sandi Metz

Confreaks在 YouTube 播放 ↗

字幕解读

Sandi Metz 以 Gilded Rose 的长条件分支为例,演示如何依靠测试逐步重构:先建立执行路径和小方法,把测试保持绿色,再提炼小对象、消息接口与工厂,最终让新增商品规则无需修改既有逻辑。她主张在理解问题前容忍重复,避免过早引入错误抽象;中间步骤可能暂时增加复杂度,但小对象能降低同时需要理解的范围。结尾讨论开闭原则、适用的浅窄继承层次,以及复杂度指标的参考价值和局限。

英文字幕轨道 · 引文按字幕原文展示,可点时间戳回看片段。

内容要点

  • 先用测试保护行为,再以小步重构建立接缝、拆分条件分支,减少一次改动影响的代码范围。
  • 重复代码有时比错误抽象更容易处理;等待更多需求信息,能帮助判断哪些变化应抽象在一起。
  • 通过对象角色、消息传递和工厂把选择对象与对象行为分开,可让新规则扩展而不修改旧逻辑。
视频章节 6
  1. 小类与小方法的方向
  2. 用 Squint Test 识别复杂度
  3. 测试保护下的小步重构
  4. 保留重复,避免错误抽象
  5. 开闭原则与对象角色
  6. 继承边界与最终设计
具体观点与证据 3

重构中尚未看清所有行为时,保留重复往往比过早提取错误抽象成本低;可以先标记重复,等更多案例提供信息。

不把重复本身当优点,而是比较未知抽象的风险。

It is far cheaper to keep duplication than it is to have to mess with the wrong abstraction.
探索此观点 →

用工厂选择合适对象,再通过统一消息执行行为,可把类型选择规则与具体业务动作分离。

Gilded Rose 重构示例,配置映射仍需维护。

I have separated the reason I'm switching from the thing I do when I switch.
探索此观点 →

重构的中间步骤可能增加复杂度,不能因每步指标暂时上升就否定通向更小对象的整体重构。

讲者强调有行为测试与明确设计方向的重构,不是为无限复杂化辩护。

Intermediate refactorings often make code more complicated, but if you know the rules,
探索此观点 →
补充字幕原文 2

演讲的核心建议是拆小类与方法,并降低组件彼此需要了解的内容。

make smaller things

面对重复与错误抽象的选择时,作者倾向先保留重复,以免抽象增加后续修改成本。

It is far cheaper to keep duplication than it is to have to mess with the wrong abstraction.
解读边界

演讲围绕一个 Ruby Kata 展开,提出的重构路径依赖测试覆盖和对对象设计原则的判断;Flog 等复杂度指标仅作辅助,并不等同于可读性或维护成本。

相关视频与证据 4

不同设计路径都在写类,却对面向对象给出不同建议

Metz 建议把类、方法和相互依赖变小;另一位讲者主张转向过程式风格,却明确说问题并不在类本身。两个片段帮助区分语言构造与组织代码的方式。

当前视频

RailsConf 2014 - All the Little Things by Sandi Metz

演讲的核心建议是拆小类与方法,并降低组件彼此需要了解的内容。

make smaller things
关联视频

Object-Oriented Programming is Bad ↗

作者明确把问题放在某类组织耦合上,而非直接否定类。

the problem is really not classes per se
▶ 1:37–1:42 · 观看片段

适用边界 不能从标题推断两人对每种类设计都直接对立;这些片段不构成相互回应。

区分范围小对象与小接口,不是同一个尺寸

Metz 谈类和方法的粒度,以及彼此知道得更少;Bloch 谈 API 暴露的功能范围,并建议拿不准时不加入。可以比较内部拆分与外部接口收缩这两个不同设计维度。

当前视频

RailsConf 2014 - All the Little Things by Sandi Metz

演讲的核心建议是拆小类与方法,并降低组件彼此需要了解的内容。

make smaller things
关联视频

How To Design A Good API and Why it Matters ↗

拿不准某项功能是否必要时,倾向于不加入接口。

When it doubt, leave it out.
▶ 24:42–24:45 · 观看片段

适用边界 更多小类不必意味着更好的公共 API;不能把两段合并成对任意粒度的越小越好。

抽象风险与模块深度的互补视角提防错误抽象,也要让必要抽象足够深

Metz 提醒保留重复有时比维护错误抽象便宜;Ousterhout 则强调深模块以简单接口隐藏大量能力。把两者并读可帮助判断抽象质量:抽象不应只是消除重复,而应真正提供稳定、足够有价值的能力边界。

当前视频

RailsConf 2014 - All the Little Things by Sandi Metz

当抽象错误时,保留重复可能比以后修改抽象更便宜。

It is far cheaper to keep duplication than it is to have to mess with the wrong abstraction.
关联视频

A Philosophy of Software Design | John Ousterhout | Talks at Google ↗

好的深模块用简单接口承载大量功能,降低调用者的理解负担。

very simple interface with a very large amount of functionality underneath it
▶ 14:24–14:29 · 观看片段

适用边界 两位讲者没有互相回应。Metz 反对的是错误抽象,并未主张避免一切抽象;Ousterhout 也没有说每段重复代码都应被抽成模块。

模块边界的互补设计小组件与值边界都在减少彼此耦合

Metz 建议把代码拆成更小的东西;Bernhardt 说明以值作为对象边界,可以替代组件之间的同步方法调用。合读可把“缩小组件规模”和“选择低耦合交互方式”看作两个不同但互补的边界设计手段。

当前视频

RailsConf 2014 - All the Little Things by Sandi Metz

将代码拆成较小的对象或方法,缩小需要同时理解的范围。

make smaller things
关联视频

Ruby Conf 12 - Boundaries by Gary Bernhardt ↗

对象之间可以用返回或接收的值作为边界,降低同步方法调用带来的耦合。

we now have values as boundaries.
▶ 10:17–10:24 · 观看片段

适用边界 小类或小方法不自动形成良好边界;值边界的好处取决于交互是否适合通过数据传递表达。

Hacker News 评论

查看 HN 原评论 ↗