技术开发 频道

谷歌首席Java架构师谈数学与程序员关系

  Seibel:设计Java集合类这样的,一个具体的自包含的API,设计规范需要有多具体?

  Bloch:我敢说比你想的要粗略多了。任何复杂的编程都需要API设计,因为大程序都需要模块化,你必须设计模块之间的接口。

  优秀的程序员把问题分块,孤立地去看他们。这样做的理由有几条。比如,你可能会在无意中创造出好用的、可重用的模块。如果你写一个单一的系统,它越来越大,等你想分块的时候,就无法找到清晰的边界,最后系统就变成了一个无法维护的垃圾。所以我断言,无论你是否把自己看成API设计者,把问题分块都是最好的编程方法。

  这就是说,编程的世界非常广阔。如果对你来说编程就是写HTML代码,那么这也许不是最好的编程方法。但是,我认为对于大多数编程来说,这就是最好的方法。

  Seibel:所以你希望系统由不同的模块松散地耦合在一起。要达到这样的目标,现在有两种不同的看法。一种是坐下来实现设计模块间的API,像你前面提到的那样。另外一种是,“构建可运行的最简系统,然后毫不留情地重构”。

  Bloch:我不认为这两种方法有什么冲突。某种程度上,我谈的就是测试先行编程,以及对API的重构。如何测试你的API呢?在实现API之前编写它的测试用例。虽然我还不能运行用例,但我在进行测试先行的编程:实现用例后看API是否能完成任务,我用这样的方法测试API的质量。

  Seibel:也就是说你写好使用API的用户代码,然后评审代码:“这就是我要的代码吗?”

  Bloch:对!有时候你都不用走到评审用户代码的这个阶段。写代码的时候可能就会有感悟,“写不出来,我忘了这部分API的功能了。”或者“这代码写起来太乏味了,一定哪里出错了。”

  这跟你多么优秀无关。不用API写代码,就不可能看出API有什么问题。设计了一个东西,使用了才知道:“哦,错的这么离谱。”如果这是在你浪费大量时间基于这个API写了无数代码之前的话,那么这就是一个重大的胜利。所以,我谈得更多的是测试先行编程和对API的重构,而不是重构API的实现代码。

  说到能够运行的最简程序,我完全赞同这种提法。API设计有一条基本原则:疑则不用。它必须是完全满足你关心的所有用例的最简系统。而不是说“把乱七八糟的代码堆在一起”。有很多格言警句说明了这点。我最喜欢的一条是:“简单没那么容易做到。”坊间认为就是Thelonious Monk说的,实际不是,是误传。

  没人喜欢烂软件。人们提倡“构建可运行的最简系统,然后毫不留情地重构”,而不提倡“写垃圾代码”,更不会说“不要做前期设计”。我曾跟Martin Fowler讨论过这个问题。他坚信,只有仔细推敲要做的东西,系统才会有合理的形状和结构。他说过,“不要在写代码前先写下247页的设计规范。”我很赞同。

  我不赞同Martin的一点是:我认为测试不能用来取代文档。只要你写了别人编程时可以利用的代码,你就需要做出精确的说明,而测试确保这些代码符合你给出的说明。

  所以两大阵营确实有些不同意见,但是我认为他们之间的鸿沟没有某些人想象的那么大。

  Seibel:既然你提到了Fowler,咱们就聊聊他。他写了很多关于UML的书,你把UML当设计工具用过吗?

  Bloch:没有。我觉得用UML做些图表让其他人理解起来可能更容易。但是说实话,我根本记不住那些组件应该是方的还是圆的。

0
相关文章