[学习笔记] 《代码整洁之道》— 第8章 边界
我们很少控制系统中的全部软件。
- 有时我们购买第三方程序包或使用开源代码;
- 有时我们依靠其他团队打造组件或子系统。
无论哪种情况,我们都得将外来代码干净利落地整合进自己的代码中。
本章介绍一些保持软件边界整洁的实践手段和和技巧。
使用第三方代码
-
在接口提供者和使用者之间,存在与生俱来的张力。
- 第三方程序包和框架提供者追求普适性
- 使用者则想要集中满足特定需求的接口。
- 这种张力会导致系统边界出现问题。
-
如果你的应用程序需要一个包容 Sensor 类对象的 Map 映射图,大概会是这样:
Map sensor = new HahMap();
当代码的其他部分需要访问这些 sensor, 就会有这样的代码:
Sensor s = (Sensor)sensors.get(sensorId);
这行代码一再出现。代码调用端承担了从 Map 中取得对象并将其转换为正确类型的职责。行倒是行,但却不是整洁代码!而且这行代码并未说明自己的用途。
通过对泛型的使用,这段代码可读性可以大大提高:
Map<Sensor> sensors = new HashMap<Sensor>(); ... Sensor s = sensors.get(sensorId);
不过, Map<Sensor> 提供了超出所需/所愿的功能问题仍未解决。
使用 Map 的更整洁的方式如下:
public class Seneors{ private Map sensors = newHashMap(); public Sensor getById(String id){ return (Sensor) sensors.get(id); } //片段 }
- 边界上的接口(Map)是隐藏的。它能随来自应用程序其他部分的绩效的影响而变动。
-
不要将 Map (或在边界上的其他接口)在系统中传递。
- 如果你是用类似 Map 这样的边界接口,就把它保留在类或近亲类中。
- 避免从公共 API 中返回边界接口,或者将边界接口作为参数传递给公共 API。
学习性测试
- 学习第三方代码很难。整合第三方代码也很难。
- 不要在生产代码中试验新东西,而是编写测试来遍览和理解第三方代码。------ 学习性测试
- 学习性测试毫无成本。
- 无论如何我们都得学要使用的 API;
- 编写测试则是获得这些知识的容易而不影响其他工作的途径。
- 学习性试在投资上有正面回报。
- 当第三方程序包发布新版本,我们可以运行学习性测试,看看程序包的行为有没有改变。
- 学习性测试确保第三方程序包按照我们想要的方式工作。
- 学习性测试毫无成本。
- 无论你是否需要学习性测试来学习,总要有一系列与生产代码中调用方式一致的输出测试来支持整洁的边界。
使用尚不存在的代码
- 编写我们想得到的接口,好处之一是它在我们的控制之下。
- 有助于保持客户代码更可读
- 且集中于它该完成的工作。
整洁的边界
边界上会发生有趣的事。
- 改动
- 有良好的软件设计,无需巨大投入和重写即可进行修改。
- 边界上的代码需要清晰地分割和定义了期望的测试。
- 避免我们的代码过多的了解第三方代码中的特定信息。
- 通过代码中少数几处引用第三方边界接口的位置来管理第三方边界。
参考文献
[1] Robert C. Martin 著,韩磊 译,《代码整洁之道》,北京:人民邮电出版社,2010.1(2018.9 重印), ISBN 978-7-115-21687-8。