元程序设计
细节会弄乱我们整洁的代码——特别是如果它们经常变化。每当我们必须去改动代码,以适应商业逻辑、法律或管理人员个人一时的口味的某种变化时,
我们都有破坏系统或引入新bug的危险。所以我们说“把细节赶出去!”把它们赶出代码。当我们在与它作斗争时,我们可以让我们的代码变得高度可配置和“柔软”——就就是,容易适应变化。
要用元数据(metadata)描述应用的配置选项:调谐参数、用户偏好、安装目录等等。元数据是数据的数据,最为常见的例子可能是数据库schema或数据词典。
要配置,不要集成
但我们不只是想把元数据用于简单的偏好。我们想要尽可能多地通过元数据配置和驱动应用:为一般情况编写程序,把具体情况放在别处——在编译的代码库之外。
将抽象放进代码,细节放进元数据
曳(yè)光弹
译著中对曳光弹的描述有点难懂,百科中的解释:曳光弹是一种装有能发光的化学药剂的炮弹或枪弹,用于指示弹道和目标。曳光弹在光源不足或黑暗中可显示出弹道,协助射手进行弹道修正,甚至作为指引以及联络友军攻击方向与位置的方式与工具。
这个类比也许有点暴力,但它适用于新的项目,特别是当你构建从未构建过的东西时。与枪手一样,你也设法在黑暗中击中目标。因为你的用户从未见过这样的系统,他们的需求可能会含糊不清。因为你在使用不熟悉的算法、技术、语言或库,你面对着大量未知的事物。同时,因为完成项目需要时间,在很大程度上你能够确知,你的工作环境将在你完成之前发生变化。
经典的做法是把系统定死。制作大量文档,逐一列出每项需求、确定所有未知因素、并限定环境。根据死的计算射击。预先进行一次大量计算,然后射击并企望击中目标。然而,注重实效的程序员往往更喜欢使用曳光弹。
用曳光弹找到目标
曳光代码并非用过就扔的代码:你编写它,是为了保留它。它含有任何一段产品代码都拥有的完整的错误检查、结构、文档、以及自查。它只不过功能不全而已。
但是,一旦你在系统的各组件间实现了端到端(end-to-end)的连接,你就可以检查你离目标还有多远,并在必要的情况下进行调整。一旦你完全瞄准,增加功能将是一件容易的事情。
曳光开发与项目永不会结束的理念是一致的:总有改动需要完成,总有功能需要增加。这是一个渐进的过程。
曳光开发其实大家或多或少都在参与。新项目创建时搭建框架代码,逐渐为框架添加功能正是这样一个过程。我们会在框架中让关键流程能够运行,以检验新技术
在真实环境中的表现与预研的结果是否一致;检验整体设计是否有明显的性能问题;让用户尽早看到可工作的产品以提供反馈;为整个团队提供可以工作的结构与集成平台,大家只需要关心增加功能代码让框架更丰满。
曳光开发和原型模式有明显区别。原型中的代码是用过就扔的,寻求以最快的速度展示产品,甚至会采用更高级的语言。曳光代码虽然简约,但却是完成的,它拥有完整的错误检查与异常处理,只不过是功能不全而已。