这两天在读kissy的源代码,从一开始我就对它的mix()函数充满了敌意。因为无论从哪个角度来看,那都是一个极其低效的实现。不过深入了解这个框架之后,我对kissy中的新的系统构建的模型产生了兴趣,而这种系统构建的方式,也正是由mix()所带来的。
一、对象系统
我们先了解一下对象系统。在《JavaScript语言精髓与编程实践》中谈到过,面向对象系统有三种对象的继承方式,即原型、类和元类。这三种方式都可以构建大型对象系统。在后续讨论之前,我们在名词概念上做一些强调,所谓“对象系统”,是指由“一组对象构成的系统”,这些对象之间存在或不存在某种联系,但通过一些规则组织起来。所谓“面向对象系统”,是指以上述“对象系统”对基础延伸演化的系统,新系统满足前对象系统的组织规则。
所谓对象系统的三个要素,即继承、封装与多态,即是上述组织规则的要件。孟岩同学从C/C++出发,从另一个侧面谈论对象系统,所持的观点我相当认可,这包括所述的“对象范式的基本观念中不包括继承、封装与多态”——这一观点有其确切的背景与思考方法,值得一谈。
(http://blog.csdn.net/myan/archive/2010/10/09/5928531.aspx)
我们在这里要讨论的是“对象系统”,即,对象是如何组织起来的问题。在这个问题上,组织规则之一,就是“继承”。JavaScript中基本的继承模型是原型继承,其特点是“新对象实例的特性,复制自一个原型对象实例”。Qomo以及其它的一些项目,通过语言扩展的方式,在JavaScript上添加了类继承的模型,其特点是“对象构建自类,类是其父类的一个派生”,这里的“派生”与“特性复制”有潜在的关系,即:子类的特性也复制自父类。正是因为“派生”其实是特性复制的一种形式,所以事实上Qomo中的类继承,是通过原型继承来实现的,因为原型继承本质上也就是“特性复制”。
无论是原型继承、类继承还是这里没有进一步讨论的元类继承,继承的最终目的是构建一个“对象系统”,而不是“系统”。这一个小小的措辞上的区别,有着本质上的、深刻的意义,这也是我提及到孟岩的上一篇文章的原因。通常,由“继承”入手理解的“对象系统”其实是静态的,以至于我们面向对象系统开发的最后一步,仍然需要框架来驱动之。例如TApp.Run(),或者类似于new App(),等等。继承所带来的,主要仍然是指对象系统的组织性,而非其运行过程中的动态特性。于是我们通过更多类或其它对象系统,来将一个系统的动态特性静态化,例如将对象之间的交互关系抽取出来,变成控制类。我们做这些事情的目的,仅仅是因为我们约定了对象系统的组织规则,要面向这个对象系统开发,也必然满足(或契合)这一组织规则。组织规则限定了我们构建系统的方式——继承、封装与多态,这在一定程度上说是“对象系统构建”的一个方案,并非“系统构建”的方案。而孟岩在上文中讨论的,也正是“系统构建”的问题。所以孟岩提出两点:
•程序是由对象组成的;
•对象之间互相发送消息,协作完成任务。
其第一条,是对象系统的基本特性,是谓系统成员;第二条,是对象系统如何演进为系统的特性,是谓系统通讯。一个系统的约束,既包括其成员(以及成员的组织规则),也包括成员间的通讯。
二、用mix()来构建系统
舍弃“继承”这种方式不谈,系统构建还有其它的什么方法吗?
kissy提供了另外一种可能性,即mix(),混合。在kissy系统的核心部分,为一个系统提出了三个概念:
1、原子(meta),一个系统具有至少一个原子,原子是具有mix()能力的一个对象;
2、宿主(host),一个系统有一个依赖的宿主,表明系统的外部环境,系统只是其宿主环境中的部分内容,可以由特定的名称来区别于其它;
3、种子(seed),一个系统诞生自一个种子,种子描述系统上述的meta和host两个方面的特性。
kissy约定,一个系统诞生自一个种子,该种子通过不停地mix()而成长,变成一个复杂的系统。由种子培育成为系统的整个环境,只需要能够理解mix与host,即可以基于seed来构建任意复杂的系统。
上述的逻辑在kissy.js中,描述得相当简单:
这个系统初始化的时候,传入host与host中的系统名S。对于kissy来说,host是当前的系统环境,这里的this值,可以是javascript引擎的global,或浏览器环境的window,或某个函数或对象闭包内的当前this。而'KISSY'值,表现kissy系统在环境中的名字。按照javascript的语言约定,我们可以通过host[S]来找到既已经存在的kissy系统。
按照此前的约定,一个mix构建的系统,必然有host和mix两个性质,因为它最原始的种子(seed)就必然包括这两种性质。所以,既然我们上面是通过host[S]来访问一个“既已存在的kissy系统”,则无论该kissy系统经过了何种程度的演化,必然会包括这两种性质。
上面的构建过程尝试寻找在host[S]中寻找这两种性质,如果其中之一不存在,则尝试初始化它。例如代码:
如果host[S]是存的,则假设它是一个seed,否则初始化为一个空的对象。接下来:
如果上述的种子seed有host属性,则使用它既有的__HOST,如果没有,则置为当前环境下的host,或一个空的对象。
现在我们看到的seed,必然已经具有host属性。但是,它还“可能”缺少一个性质,即最最重要的mix()。mix()的作用其实很简单,就是从对象B将属性抄写到对象A的一个方法。而这里,之所以说是“可能”缺少,是因为如果seed是既有的mix系统,则他已经有mix()属性;如果它是第三方系统,则可能没有mix,或有一个不同的mix等等。下面的一行代码尝试用元语言的思想构建它,即:
元语言的特点是自描述的,meta.mix()可以向seed混入mix(),也可以使seed.mix()能混入其它系统或meta本身。总之在mix()的构建中,meta只需要有mix这个方法,不需要更多,也不能更少。
上一行代码的结果,是:如果seed没有自已的mix()属性,则向seed混入meta的原始的mix()。
现在,我们再看seed,必然已经具有了host和mix()属性。它本身可能是一个空对象,也可能是一个庞大的既有系统,但无论如此,它具有了这两个性质,就可以作为seed进一步的衍生。
在这一切之前,下面的代码保证它位于HOST[S],并返回这个系统:
三、mix()系统构建中的其它概念
kissy除了实现基本的mix系统之外,在core部分加入了其它的一些功能。包括除mix()之外的两种混入方法:
- augment,扩充。用mix方法,将另一些子系统s[i]的原型,混入目标子系统r的原型。
- merge,合并。用mix方法,将另一些子系统s[i],混入当前子系统S。
基本上来说,augment是通过mix来对javascript的原型系统进行扩充的方法,或是在应用系统中,结合原型机制与混入机制来构建系统。而merge只是mix方法的一个批量工具。
另外,考虑到面向对象系统中的继承特性,kissy也实现了extend(派生)方法,以提供传统的面向对象编程能力。
除了语言级别的概念之外,kissy也提供系统框架级别的一些构建能力。包括:
- app,应用。与host[S]并列的,具有同等能力的其它应用,app('XXX', ...)可以在host['XXX']上组织应用。
- namespace,命名空间。即可以组织出host[XXX].YYY.ZZZ这样的,在不同子系统中的,不同命名空间下的系统。
最后,kissy在内核中也提供简单的调试支持。
显然的,基于mix的原则,任何一个第三方的系统可以通过混入kissy来修改上述的概念,例如覆盖extend()来实现自己的对象系统构建原则,或覆盖app()来实现自己的应用组织原则。第三方系统也可以将kissy混入自身,在保障自身特性的情况下,使用kissy,以及更大规模的kissy ui系统带来的好处。
四、一点点提示
kISSY是什么?
KISSY是一个开源的javascript项目,其主体是一个前端UI开发框架,即KissyUI。本文所述的kissy是仅指其内核部分的kissy.js中的语言与框架设计思想。KISSY项目的开源网站是:http://kissyteam.github.com/
kissy怎么使用呢?
尽管在KissyUI向kissy内核化的过程中,我们提出了一些新的概念与框架模型,但事实上,我们并未改变KissyUI的任何使用惯例。从代码上来看,kissy.js和lang.js以后的其它模块,并没有任何的变化,因此如果仅是将kissy当成一个UI系统来使用,你可以参考上面的开源网站,其中既有的KissyUI文档是完全有效的,而且KissyUI本身也是一个优秀的、便捷的Web UI框架。但是,kissy系统在模向合并和组织上的能力大大增强了。例如说,我们可以开始想象下面这样的代码:
分享到:
相关推荐
### 基于IP_SAN架构的数字图书馆混合存储系统构建研究 #### 一、网络存储系统概述 随着信息技术的快速发展,数字图书馆面临着大量的数字化信息资源的管理和存储挑战。合理构建数据存储平台对于数字图书馆而言至关...
在C#编程语言中,单根继承是其面向对象...这种方式让C#程序员能够构建复杂且可扩展的系统,同时保持代码的清晰性和简洁性。在实际开发中,合理地利用接口和类的组合,可以帮助我们设计出更加符合面向对象原则的代码。
PXI平台具备良好的兼容性,能够方便地与其他总线技术的仪器设备集成在一起,形成混合总线测试系统。这种兼容性使得PXI能够在复杂的测试环境中发挥关键作用,确保整个系统的高效运行。 总之,基于PXI构建的自动化...
该方法的第一个阶段集中于人工生命系统的构建与演化,通过模拟人工生物的群体行为来产生优化问题的初始解集。这个初始解集至关重要,因为它决定了优化搜索过程的起点,而一个好的起点可以极大地提高算法避免局部最优...
随着企业上云进程的加速,混合云场景的出现对监控系统提出了更高的要求。在这样的背景下,夜莺(Nightingale)作为一个国产开源监控工具,它的出现和应用备受业界关注。 首先,了解监控系统的需求来源是至关重要的...
### ITK与VTK混合编程的关键知识...4. **构建与安装**:根据配置的结果进行构建和安装。 通过上述步骤,可以有效地将ITK和VTK集成在一起,充分发挥二者的优势,构建出功能强大且易于使用的医学图像处理与可视化系统。
2. **混合类型**:多重继承可以用来创建具有多种特质的对象,例如一个同时具有图形处理能力和文件操作能力的类。 3. **代码组织**:在大型项目中,不同的功能可能分散在多个类中。通过多重继承,我们可以将相关功能...
模板的引入也减少了对多重继承的依赖,因为它们可以用于构建通用容器,无需直接继承。 5. **修复接口** 在设计时,可能需要修复因多重继承导致的接口问题,比如不兼容的函数签名或冲突的成员。这可能需要使用访问...
混合蚁群算法是解决分布式系统任务分配问题的有效工具。分布式系统广泛应用于各种场景,例如大数据处理、云计算等,这类系统的关键技术之一就是任务分配。在分布式系统中,任务分配问题是一个典型的NP-hard问题,...
本文通过将哈密顿能量系统理论应用于混合磁路电机,成功地构建了广义耗散哈密顿系统的数学模型,并设计了非线性稳定控制器。仿真结果表明,这种方法不仅能够有效提高电机的控制性能,而且能够增强系统面对参数变化时...
本文将深入探讨QML与C++混合编程的两种主要方式。 ### 1. QML的C++组件 一种混合编程的方法是通过创建C++组件并暴露给QML使用。在C++中,你可以定义复杂的逻辑或高性能的数据处理类,然后在QML中作为对象使用。这...
在金融数学和衍生品定价领域中,混合分数布朗运动(Mixed Fractional Brownian Motion)是一个重要的研究对象,它对金融市场模型的构建有着重要的影响。混合分数布朗运动结合了布朗运动和分数布朗运动的特征,可以...
- **混合继承**:派生类同时采用单重、多重或多级继承的组合。 4. **定义派生类的格式**: 在C++中,定义派生类的格式通常如下所示: ```cpp class 派生类名 : 继承方式 1 基类名 1, 继承方式 2 基类名 2, ... ...
Java在企业级应用开发中占据主导地位,广泛应用于服务器端Web应用程序开发,包括构建大型企业级应用系统、微服务架构以及云计算解决方案。同时,Java也在移动应用领域大放异彩,尤其在Android操作系统上是主要的应用...
本文详细介绍了专家系统的设计与C#实现的相关知识点,包括基本概念、C#的特点及适用性、面向对象程序设计技术、知识表示与知识库构建、推理引擎的设计以及开发步骤。通过这些内容的学习,读者可以更好地理解如何构建...
在实际项目中,混合语言编程通常涉及系统编程语言(如C/C++)与脚本语言(如Python)的结合。具体而言: - **核心模块**:对于计算密集型的任务,通常使用C/C++编写,因为它们提供了更好的性能。 - **脚本层**:...
`Ext`是一个流行的JavaScript库,它提供了丰富的UI组件和强大的数据管理工具,同时也引入了一套完整的面向对象系统,其中包括类(Class)和继承(Inheritance)的概念。本文将深入探讨`Ext`中的继承和扩展机制。 在...
总结来说,这个压缩包文件可能涵盖了Python多重继承的基本概念、MRO的原理、如何避免和解决继承冲突、以及如何利用多重继承来构建灵活的代码结构。对于想要深入学习Python面向对象编程的开发者来说,这份资料将是一...