论KISSY中一则API的设计



这次D2上,玉伯介绍KISSY。我听下来,KISSY有不少设计和我断断续续做的PIES框架的设计是类似的(或许现在的JS类库在许多设计思路上必然会有许多共识)。但是seed、meta之类的概念就不容易理解。后来我看了一下,原来这些概念是爱民给加上的,嘿嘿。当然,即使不看爱民的解说,我们也可以了解大概思路,是系统可从seed动态演化出来。但是meta这样的抽象就有些学院派,特别是不像爱民的QoBean项目本来就是要做元编程,在KISSY内,这个抽象只对内,不对外,也不直接解决实践中构建系统的关键问题,比如namespace和module。meta的作用其实只是使得内核具有一个更加精巧的核心。所以这样过于“务虚”的抽象对于听众来说无疑是天书。

好吧,这个起头有点长,其实本篇blog想要讨论的只是KISSY中的一个很小的点:DOM.attr的API设计。

这个API(我稍作了简化)是这样滴:

attr ( element, attrName )
获取元素的属性值。

attr ( element, attrName, value )
给元素设置属性值。

你可以注意到,这里其实是函数重载(overload),两个参数是返回属性值,而三个参数是设置属性值。KISSY中有不少API都是类似的。

然而这种API设计我认为大有问题。原因很简单,重载方法(函数)的参数虽然不同,但是同样名字的方法(函数)干的事情应该是相同的。而在这里,两个重载方法(函数)做的事情却正好相反!

我们考虑一下实际编程的情况,许多时候参数本身就是一些方法调用的结果,因此整个调用序列可能就比较长。在这种情况下,你很难一眼看出这个调用到底是几个参数,因此当然也不知道这里到底是取值还是赋值。

所以这种API可能导致程序可读性的严重下降。

那么在什么情况下,相同名字而相反意义才是可行的?属性就是这样一个例子。因为a和a=(赋值)的区别还是非常明显的。然而即使如此,我们还经常遇到a=1和a==1的混淆。

另一个可行的案例有些语言是用a()和a(v)来作为getter/setter的写法。因为“没有参数”的调用和带有一个参数的调用,其区分还是相当明显的,况且这些语言中很可能允许省略无参调用的括号,那么a和a(v)的差异就更一目了然了(而且还不会有a=1和a==1的混淆)。但是,有一个参数和有两个参数的区分就不那么明显了,而像attr这个例子是两个参数和三个参数,那就更难分辨了。

所以回到最普遍的情形,对于方法(函数)的重载来说,应该坚守这个原则:重载方法(函数)干的事情应该是相同的。相比attr,setAttr和getAttr虽然多了几个字符,但是能确保程序的可读性。






你可能感兴趣的:(jquery,框架,css,正则表达式,企业应用)