《程序员修炼之道》——第二章 注重实效的途径(三)

9、 可撤销性前端

  有许多人会设法保持代码的灵活性,而你还须要考虑维持架构、部署及供应商集成等领域的灵活性。算法

  一般你能够把第三方产品隐藏在定义良好的抽象接口后面。事实上,在咱们作过的任何项目中,咱们都总可以这么作。但假定你没法那么完全地隔离它,若是你必须大量地把某些语句分散在整个代码中,该怎么办?把需求放入元数据,而且使用某种自动机制——好比Aspect或Perl——把必要的语句插入代码自身中。不管你使用的是何种机制,让它可撤销。若是某样东西是自动添加的,他就能够被自动去掉。数据库

 

10、曳光弹前端框架

  在黑暗中用机枪射击能够用曳光弹的方式。曳光弹与常规弹药交错着装在弹药带上。发射时,曳光弹中的磷点燃,在枪与它们击中的地方之间留下一条烟火般的踪影。若是曳光弹击中目标,那么常规子弹也会击中目标。服务器

  这个类比也许有些暴力,蛋它适用于新的项目,特别是你构建从未构建过的东西时。与枪手同样,你也设法在黑暗中击中目标。由于你的用户从未见过这样的系统,他们的需求可能会含糊不清。由于你在使用不熟悉的算法、技术、语言和库,你面对着大量未知的事物。同时,由于完成项目须要时间,在很大程度上你可以通知,你的工做环境将在你完成以前发生变化。架构

  

  在黑暗中发光的代码框架

  曳光弹行之有效,是由于它们与真正的子弹在相同的环境、相同的约束下工做。它们快速飞向目标,因此抢手能够获得即时的反馈。同时,从实践的角度看,这样的解决方案也更便宜。工具

  为了在代码中得到一样的效果,咱们要找到某种东西,让咱们能快速、直观和可重复地从需求出发,知足最终系统的某个方面要求。布局

  有一次,咱们接受了一个复杂的客户-服务器数据库营销项目。其部分需求是要可以指定并执行临时查询。服务器是一系列专用的关系数据库。用Object Pascal编写的客户GUI使用一组C库提供给服务器的接口。在转换为优化的SQL以前,用户的查询以相似Lisp的表示方式存储在服务器上;转换直到执行前才进行。有许多未知因素和许多不一样的环境,没有人清楚地直到GUI应该怎样工做。性能

  这是使用曳光代码的好机会。咱们开发了前端框架、用于查询的库以及用于把所存储的查询转换为具体数据库的查询的结构。随后咱们把它们几种在一块儿,并检查它们是否能工做。使用最初构建的系统,咱们所能作的只是提交一个查询,列出某个列表中的全部行,但它证实了UI可以与库交谈,库可以对查询进行序列化和解序列化,而服务器可以根据结果生成SQL。在接下啦的几个月里,咱们逐渐充实这个基本结构,经过并行地扩大曳光代码的各个组件增长新的功能。当UI增长了新的查询类型时,库随之成长,而咱们也使SQL生成变得更为成熟。

  曳光代码并不是用过就扔的代码:你编写它,是为了保留它。它含有任何一段代码产品都拥有的完整的错误检查、结构、文档、以及自查。它只不过功能不全而已。可是,一旦你在系统的各组件间实现了端到端的链接,你就能够检查你离目标还有多远,并在必要的状况下进行调整。一旦你彻底瞄准,增长功能将是一件容易的事。

  曳光开发与项目永不会结束的理念是一致的:总有改动须要完成,总有功能须要增长。这是一个渐进的过程。

  另外一种传统方法是一种繁重的工程方法:把代码划分为模块,在真空中对模块进行编码,把模块组合成子配件,再对自配件进行组合,直到有一天你拥有完整的应用为止。直到那时,才能把应用做为一个总体呈现给用户,并进行测试。

  曳光代码方法有许多优势:

  • 用户可以及早看到能工做的东西。若是你成功地就你在作的事情与用户进行了交流,用户就会知道他们看到的是还未完成的东西。他们不会由于缺乏功能而失望;他们将由于看到了系统的某种可见的进展而欣喜陶醉。他们还会随着项目的进展作出贡献,增长他们的“买入”。一样是这些用户,他们极可能也会告诉你,每一轮“射击“距离目标有多接近。
  • 开发者构建了一个他们能在其中工做的结构。最使人畏缩的纸是什么也没写的白纸。若是你已经找出应用的全部端到端的交互,并把它们体如今代码里,你的团队就无须再无中生有。这让每一个人都变得更有生产力,同时又促进了一致性。
  • 你有了一个集成平台。随着系统端到端地链接起来,你拥有了一个环境,一旦新的代码段经过了单元测试,你就能够将其加入该环境中。你将天天进行集成(经常是一天进行屡次),而不是尝试进行大爆炸式的集成。每一个新改动的影响都更为显而易见,而交互也更为有限,因而调试和测试将变得更快、更准确。
  • 你有了可用于演示的东西。项目出资人与高级官员每每会在最不方便的时候来看演示。有了曳光代码,你总有东西能够拿给他们看。
  • 你将可以感觉到工做进展。在曳光代码开发中,开发者一个一个地处理用例。作完一个,再作下一个。评测性能、并向用户演示你的进展,变得容易了许多。由于每一项个别的开发都更小,你也避免了建立这样的总体式代码块:一周又一周,其完成度一直是95%。

 

  曳光弹并不是总能命中目标

  曳光弹告诉你击中的是什么。那不必定老是目标。因而你调整准星,直到彻底击中目标为止。这正是要点所在。

  曳光代码也是如此。你在不能100%肯定该去往何处的情形下使用这项技术。若是最初的几回尝试错过了目标——用户说:“那不是个人意思”,你须要的数据在你须要它时不可用,或是性能好像有问题——你不该感到惊奇。找出怎样改变已有的东西、让其更接近于目标的办法,而且为你使用了一种简约的开发方法而感到高兴。小段代码的惯性也小——要改变它更容易、更迅速。你可以搜集关于你应用的反馈,并且与其余任何方法相比,你可以话费较小的代价、更为迅速地生成新的、更为准确的版本。同时,由于每一个主要的应用组件都已表如今你的曳光代码中,用户能够确信,他们所看到的东西具备现实基础,不只仅是纸上的规范。

  

  曳光代码 vs 原型制做

  你也许会想,这种曳光代码的概念就是原型制做,只不过有一个更富“进攻性”的名字。他们有所区别。使用原型,你是要探究最终系统的某些的方面。使用真正的原型,在对概念进行了实验以后,你会把你捆扎在一块儿的不管什么东西扔掉,并根据你学到的经验教训从新适当地进行编码。

  例如,假定你在制做一个应用,其用途是帮助运货人肯定怎样把不规则的箱子装入集装箱。

  除了考虑其余一些问题,你还须要设计直观的用户界面,而你用于肯定最优集装箱方式的算法很是复杂。

  你能够在GUI工具中为最终用户制做一个用户界面原型。你的代码只能让界面响应用户操做。一旦用户对界面布局表示赞成,你能够把它扔掉,用目标语言从新对其进行编码,并在其后加上商业逻辑。与此相似,你能够为实际进行装箱的算法制做原型。你能够用像Perl这样的宽松的高级语言编写功能测试,并用更接近机器的某种语言编写低级的性能测试。不管如何,一旦你作出决策,你都会从新开始在其最终环境中为算法编写代码,与现实世界接合。这就是原型制做,它很是有用。

  曳光代码方法处理的是不一样的问题。你须要知道应用怎样结合成一个总体。你想要向用户演示,实际的交互式怎样工做的,同时你还想要给出一个结构骨架,开发者能够在其上增长代码。在这样的状况下,你能够构造一段曳光代码,其中含有一个极其简单的集装箱装箱算法实现和一个简单算法、但却能工做的用户界面。一旦你把应用中的全部组件都组合在一块儿,你就拥有了一个能够向你的用户和开发者演示的框架。接下来的时间里,你给这个框架增长新功能,完成预留了接口的例程。但框架仍保持完整,而你也知道,系统将会继续按照你第一次的曳光代码完成时的方式工做。

  其间的区别很是重要,足以让咱们再重复一次。原型制做生成用过就扔的代码。曳光代码虽然简约,但倒是完整的,而且构成了最终系统的骨架的一部分。你能够把原型制做视为在第一次曳光弹发射以前进行的侦察和情报搜集的工做。

相关文章
相关标签/搜索