一种API代码结构的设计思路

Twitter's API Playground

Prologue

在写API的过程中有这样三种产物

  • 文档

    几乎没人爱写文档,写了也懒得维护。可是同时API的文档对于其他程序员来说又是赖以生存的必需品。因此大家对文档都是爱恨交加,恨自己要维护文档,爱别人写好的漂亮文档;恨别人的烂文档错文档,爱自己随便乱写乃至不写文档。

  • 操场

    比文档更高一个层次的奢侈品,不用写代码简单点点或者repl形式马上就能探索接口的行为。不像仅对别人,操场的存在对自己开发接口也是很有帮助的。

    没操场的时候,大家往往人肉建一个文件当操场用,在里面各种玩API,但使着编译型语言的兄弟们没那么好运,他们更需要有操场。

    当然如果实践TDD或BDD的话,用例大概能代替操场一部分的作用,但这只对写接口的人管用。对调用接口的人来说,操场的作用是难以取代的。

  • 字段校验逻辑

    自己写接口的时候必须要做的事情。没做那是100%bug。

想想这三个产物的共同特点是什么?插入一段广告,哦不,我先把他们捏成一张表

Easy ECMA 1

简单易懂的ECMA规范导读1

最近混SF,恰巧又逢工作方面有了NodeJS的机会,迫切地有教别人怎么写JS的需求,
我发现JS这个东西其实真没那么容易理解。

为了加深和纠正自己对JS的理解,也为了以后能直接甩别人一脸文章,所以开始挖这样一个大坑:简单易懂的ECMA规范导读
希望能以专题的形式有线索地基于ECMA标准介绍Javascript的方方面面。本文不是ECMA标准的中文翻译,也不是Javascript的入门教程,
本文虽然以JS的常见问题切入,但并不适合想要快速了解这些问题的人(Google才是快速了解问题的正解)。
本文的聚焦于标准如何决定了JS的各种行为,JS引擎的水面下在发生些什么。

本文描述的是ECMA262的5.1版本 也是现在最为流行和主流的标准,
现代浏览器和NodeJS默认均遵循此标准。尽量以英文原版为基础,为了流畅,可能会使用某些名词的中文翻译,
但会将匹配的英文名词以此种样式中出现一次以避免误解。

Topic1. that’s this

我们的第一个话题是:this指向哪里?

Design story of LitPHP

LitPHP(官网 | Repo) 昨天正式开源了,这是喜欢框架的我的第一个自认为能拿出手的作品。终于有了这么个作品让我相当地感想万千。先贴上12个类+1个接口的类图

LitPHP的设计哲学

Introducing Backbone.Joint

接触Backbone已经半年有余,也有机会在各种项目中实践。自己的mcfog/Backbone.Joint 也从一个玩票儿小lib慢慢演化成一个经受过生产环境考验的backbone扩展。一直没有机会写点字介绍一下,终于在14年新春之际,码了这么一篇介绍出来。

Backbone.Joint 从13/06/14开始挖坑,7月7日登上github至今,可以说已经进入一个比较稳定的0.1版本。在Readme.md中我写的desc是这样描述这个扩展的

another extension of backbone.js aims to support common situation with small & flexible codebase

Backbone.Joint主要针对Backbone.View,对Backbone.ModelBackbone.Collection的补充暂时在另一个repo Backbone.storageEngine 中。由于最开始的练手性质,开发语言一直是coco,这是一种coffeescript的方言。

a browser incompatibility behavior about jquery and unattached element

摘要

  • jQuery.fn.hide 会读取元素的display样式
  • 读取尚未插入dom树的脱机元素的样式时,不同浏览器行为不同

场景

在一段显示错误提示的代码中,发现firefox下显示异常,错误提示tips的宽度没有自适应内容而是占满了整个容器。inspect后发现,本应是由CSS控制的display:inline-block被元素的style="display:block"覆盖,chrome下没有这个问题

inspiring CDUK the modularized and flexible docco

最近在看Backbone&Underscore的时候,对他们的annoted source(backbone / underscore)产生了好感,然后发现他们都是用
Docco 来做的。

后来顺藤摸瓜发现除了类似backbone/underscore的将注释按markdown写的做法,还有更加彻底的将代码写进markdown中的做法,coffeescript已经有支持(literate-coffeescript)。

挖进源码看docco,我发现他的可扩展性存在问题,用少量代码迅速完成了核心功能但并不易扩展。最近又手痒的厉害于是干脆挖坑自己写一个literal programming用的工具。

这里记录下最初的目的和一些想法,目前的进度是基于markdown四空格的lexer已经可以跑了。

grunt-coco released

最近在看各种自动化工具,有集成化程度高,比起编译工具更像“IDE减文本编辑”的mimosajs,也有被业界广泛认可,开放易配置的gruntjs。作为一个coco语言支持者,看自动化工具当然是先看能不能支持coco。

An elegant design to unify async and sync callback based on promise object

在JS代码的设计中,“回调”是非常重要而有效的手段,这里讨论的是框架需要获取回调结果的,更加注重IoC的回调。(另一种回调的使用往往更接近订阅者模式,强调信息的单向下发)往往框架代码需要获取某些信息,但如何获取的逻辑需要留待使用者实现,此时回调就是非常直接的选择。

获取回调的输出信息有最直接的使用返回值(同步),但异步有时是无法避免的。本文不准备讨论设计回调时应该设计成同步返回还是异步返回,而是讨论如何简洁而优雅地兼容两者,使回调既能够直接返回结果,又可以通知框架等待异步返回结果。

DSL style javascript design

组织大表单应用中javascript代码的一种方法

问题,动机,目的

超过一屏,属性复杂到一定程度的录入界面/系统中,缺乏良好架构的javascript代码往往容易失控。尤其是当规模从小型表单开始逐渐变大时,javascript代码很容易演变成已DOM为核心的、缺乏结构、满是hack且难以维护的状态。

我认为良好可维护的JS代码应该具有以下的特性

  • 单个文件应该控制在一千行以内
  • 依赖管理和合并,开发应该单看一个JS文件就知道它依赖别的哪些代码,而不是在HTML中直接列举所有依赖,或者更糟,把所有超过2个页面要用的JS全写一起。
  • 良好的代码复用,清晰的模块划分
  • 改变字段的表现形式或逻辑时,不应该需要修改/考虑/知道其他字段的逻辑和展现形式。改变DOM树结构、更换表单控件等改变展现方式的需求不应当对JS产生毁灭性打击。

前三个问题基本可以归结为,超过一千行的或是需要复用的JS代码使用RequireJS / SeaJS 等方案进行分解和管理。由于这是复杂JS工程的共性,这里不多做展开讨论。本文主要关注最后一点,也就是如何解除字段逻辑和展示之间的耦合,如何解除字段和其他字段的耦合。