Ruby Conf 12 - Boundaries by Gary Bernhardt
ConfreaksYouTube ↗
延伸阅读 3
字幕解读
Gary Bernhardt 从隔离测试的困境出发:mock 能让测试更快,却可能掩盖真实对象之间的不匹配。他借助不可变值拆分计算与副作用,把决策放进函数式核心,把数据库、邮件等依赖留给命令式外壳,再将这种边界扩展到线程与进程通信。问答也明确了性能、Rails 集成和案例规模的限制。
自动字幕 · 引文按字幕原文展示,可点时间戳回看片段。
内容要点
- 以值作为边界,减少为了隔离测试而模拟复杂对象交互的需要。
- 核心承担决策、外壳连接外部依赖:分别采用单元测试与必要的集成测试。
- 不可变对象也可以有方法;这是逐步改进架构的方向,不是要求所有代码纯函数化。
视频章节 6
- 隔离测试解决了什么
- mock 与真实系统不一致的风险
- 为什么值天然容易隔离
- 函数式核心与命令式外壳
- 将值边界扩展到并发
- 问答:Rails、规模与性能限制
具体观点与证据 3
隔离测试若替身错误描述真实依赖契约,会出现测试通过但生产失败;检查方法名或参数数目仍不能保证算法协作正确。
批评的是边界失真,非断言所有模拟对象都无效。
if you don't stub the boundary correctly, your test will pass and your production system will be wrong.函数核心承担决策并以值输入输出,命令外壳连接数据库和邮件等依赖,因此可分别采用大量快速逻辑测试与少量边界集成测试。
不是取消集成测试,外壳仍需验证。
the expired users class makes all the decisions and the sweeper class has all the dependencies.把可序列化的值作为组件边界后,同一计算更容易迁移到消息传递的进程边界,串行与并行组织可以调整。
实际并行能力仍取决于运行时与任务分解。
Values in your system afford shifting process boundaries.补充字幕原文 2
以值代替同步方法调用作为交互边界。
we now have values as boundaries.函数式核心外仍需要处理 I/O 的命令式外壳。
an imperative shell that surrounds the functional core.解读边界
本上传版本含长段问答。讲者的演示系统较小;未证明任意规模系统都能获得同等收益。