本文要介绍的工作流是我最近才想出来的, 当然也借鉴了不少其他人的经验,但是,这不是重点,重点是此工作流要解决我目前遇到的问题。

我的问题主要有:

  1. 当我要完成一个代码 feature 或者要修复一个严重的 Bug 的时候,我无法准确预估我需要的时间。
  2. 当我重构一些代码时候,很容易犯一些低级的错误,这让我显得很不专业。
  3. 在解决复杂的问题的时候,我经常要试错然后不断地改进,中间会有推倒重来的可能。
  4. 对于我以前写的有一些代码,要理解它们有一定的难度。

{{{more}}}

它是什么?

一句话就是: GTD -> DDD -> RDD -> TDD/BDD -> Coding

GTD -- Getting Things Done

GTD 是一个时间管理方法,还有一本书专门介绍它,叫做《Getting Things Done 无压力工作的艺术》。

采用 GTD 来管理个人的时间,可以让自己的时间利用率最大化,把有限的时候花在最有价值的事情上面。

因为我们现在有电脑和各种智能设备,它们很容易吸引我们的注意力,这无形中会消耗我们大量的时间。

这里我就不介绍如何实践 GTD 了,对于我而言,最好的 GTD 工具自然是 Emacs 的 Org-mode,当然也有其它工具可供选择。

当我每天打开电脑,第一件事情就是检查我的 org-agenda 上面的 todo 事项,一般我会列一些 habit 在上面。比如锻炼身体,逛 reddit,阅读 rss 等。

此时,agenda view 上面可能还有一些 project todo 事项,一般而言,这些事项不可能在短时间内完成,我会安排一天中的时间来优先处理它们(比如 schedule)。

当 agenda view 上面没有 todo 事项的时候,我会从我的历史 todo 中找到“重要且紧急”的 todo 列表,然后根据实际情况 schedule 一些到 agenda 中去。

只要 agenda 中没有安排的事情,我都不去做!这一点非常关键。 如果你打开一个网站,看到一篇不错的文章就开始阅读,发现一个不错的 Github 仓库就立马 clone 下来把玩。 这样是非常浪费时间的,而且效率也不高。

另外,对于 project,我会把它分解成一系列小的 todo item,然后在实际做这些 item 的时候,我会用 org-pomodoro 来 track 我花掉的时间。这样,等项目做完, 我就可以知道我一共在这个项目上面花了多少时间。这也有利于以后做新任务的时候做时间预估。(这里的项目定义参考《无压力工作的艺术》一书)

DDD -- Document Driven Development

我这里使用的是 Org-mode 的文学编程,除了可以写文档,还可以非常方便地在文档里面插入代码和图表,最后可以导出 HTML 和 PDF 供自己和他人阅读。

文档驱动开发主要是针对一些复杂的技术问题和一些重要的技术决策来的。很多时候我们对于一个问题束手无策,可能是我们还没能理解清楚这个问题。换句话说, 就是我们连问题本身是什么可能都还没搞清楚,何谈解决它。

要理解一个问题,不仅仅是识别它本身,还包括它的约束和上下文。

所谓的“分析和设计”不止是画 UML 图和写各种设计文档,这些活动本质上是为了让我们更好地理解我们面临的问题。只有当我们完全理解了问题之后,我们才有可能找到一个简单清晰的解决方案。

如果你把思考过程写下来,把讨论过程记录下来,那么你就有机会针对此问题的理解进行深层次的迭代。另外,对于日后维护代码的人来说,这些文档也是宝贵的参考资料。

RDD -- REPL Driven Development

这个听起来挺新鲜的,我也是最近才听说的,不过这个真的非常管用。

我现在写程序如果没有 REPL 感觉很不爽,比如写 C++,编译等半天,非常低效,而且一点也不 Fun。我还是喜欢 Lisp 和 Javascript。

如果在做分析和设计的时候可以写一些代码,它会帮助你更好地理解你的问题和解决方案。它相比于制作原型开销要小得多,而且这个过程非常有趣。

另外,当你要修改一段代码的时候,如果有 REPL,你就可以在程序运行起来后,动态地 hack,进而更好地理解此程序的逻辑,做 web 开发的同学肯定深有体会。

REPL 在验证 API 和 Idea 方面会比 Org-mode 的 babel 更方便。

TDD/BDD -- Test Driven Development or Behavior Driven Development

这两个术语已经被炒得很热了,我这里就不多说了。

在具体实践的时候,注意一定要先写测试,然后让测试失败,再写代码,让测试通过,然后重构,得到简单和优雅的代码。

简言之,即 Failed -> Passed -> Refactor。

因为在实践 TDD 的时候,你可能会运行测试例上百次,所以方便的工具可以让这个过程变得不那么枯燥。

Emacs 当仁不让。我这里拿 node.js 来说,我现在用的测试框架是 mocha,通过分屏在 Emacs 里面开一个 terminal,可以非常方便地运行测试例。 我甚至可以写一段 lisp 代码,让我在保存测试代码的时候,自动运行测试。

好的工具可以让我很容易进入一种“流”的状态,然后效率自然大大地提升了。

Coding -- 开始编码

关于编码的问题不是本文的重点,惟一需要强调的是,我们的目标是编写:

简单,优雅和可维护的代码。

另外,不要一味地往代码里面加入过多的 feature,因为简单的 feature 堆砌并不能解决任何人的问题。

我们关心的是解决具体的问题,而不是添加更多的功能。而且你能保证新加的功能本身不会制造更多的问题吗?

总结

工作流千万种,找到最适合自己的才是最重要的。

也欢迎大家和我交流自己的工作流。