[size=medium]
在[url=http://www.d2forum.org/d2/5/]这次D2[/url]上,玉伯[url=http://www.slideshare.net/taobaoued/kissy-mechanism-6284467]介绍[/url]了[url=https://github.com/kissyteam/kissy]KISSY[/url]。我听下来,KISSY有不少设计和我断断续续做的PIES框架的设计是类似的(或许现在的JS类库在许多设计思路上必然会有许多共识)。但是seed、meta之类的概念就不容易理解。后来我[url=http://blog.csdn.net/aimingoo/archive/2010/12/08/6062997.aspx]看了一下[/url],原来这些概念是爱民给加上的,嘿嘿。当然,即使不看爱民的解说,我们也可以了解大概思路,是系统可从seed动态演化出来。但是meta这样的抽象就有些学院派,特别是不像爱民的QoBean项目本来就是要做元编程,在KISSY内,这个抽象只对内,不对外,也不直接解决[b]实践中[/b]构建系统的关键问题,比如namespace和module。meta的作用其实只是使得内核具有一个更加精巧的核心。所以这样过于“务虚”的抽象对于听众来说无疑是天书。
好吧,这个起头有点长,其实本篇blog想要讨论的只是KISSY中的一个很小的点:[url=http://kissyteam.github.com/kissy/docs/dom/dom-attr.html]DOM.attr[/url]的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这个例子是两个参数和三个参数,那就更难分辨了。
所以回到最普遍的情形,对于方法(函数)的重载来说,应该坚守这个原则:[b]重载方法(函数)干的事情应该是相同的。[/b]相比attr,setAttr和getAttr虽然多了几个字符,但是能确保程序的可读性。
[/size]
在[url=http://www.d2forum.org/d2/5/]这次D2[/url]上,玉伯[url=http://www.slideshare.net/taobaoued/kissy-mechanism-6284467]介绍[/url]了[url=https://github.com/kissyteam/kissy]KISSY[/url]。我听下来,KISSY有不少设计和我断断续续做的PIES框架的设计是类似的(或许现在的JS类库在许多设计思路上必然会有许多共识)。但是seed、meta之类的概念就不容易理解。后来我[url=http://blog.csdn.net/aimingoo/archive/2010/12/08/6062997.aspx]看了一下[/url],原来这些概念是爱民给加上的,嘿嘿。当然,即使不看爱民的解说,我们也可以了解大概思路,是系统可从seed动态演化出来。但是meta这样的抽象就有些学院派,特别是不像爱民的QoBean项目本来就是要做元编程,在KISSY内,这个抽象只对内,不对外,也不直接解决[b]实践中[/b]构建系统的关键问题,比如namespace和module。meta的作用其实只是使得内核具有一个更加精巧的核心。所以这样过于“务虚”的抽象对于听众来说无疑是天书。
好吧,这个起头有点长,其实本篇blog想要讨论的只是KISSY中的一个很小的点:[url=http://kissyteam.github.com/kissy/docs/dom/dom-attr.html]DOM.attr[/url]的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这个例子是两个参数和三个参数,那就更难分辨了。
所以回到最普遍的情形,对于方法(函数)的重载来说,应该坚守这个原则:[b]重载方法(函数)干的事情应该是相同的。[/b]相比attr,setAttr和getAttr虽然多了几个字符,但是能确保程序的可读性。
[/size]