`
tulunta
  • 浏览: 360268 次
文章分类
社区版块
存档分类
最新评论

继承与混合,略谈系统的构建方式

 
阅读更多

这两天在读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系统在模向合并和组织上的能力大大增强了。例如说,我们可以开始想象下面这样的代码:

分享到:
评论

相关推荐

    混合音乐推荐系统-Track Stacking-毕业设计.zip

    Java在企业级应用开发中占据主导地位,广泛应用于服务器端Web应用程序开发,包括构建大型企业级应用系统、微服务架构以及云计算解决方案。同时,Java也在移动应用领域大放异彩,尤其在Android操作系统上是主要的应用...

    MoarVM:为6model对象系统构建的运行时-开源

    MoarVM是“运行时元模型”的缩写,是为Rakudo Perl 6编译器和NQP编译器工具链构建的现代虚拟机。 大多数Perl 6程序员都使用MoarVM。... 它与进行继承,角色,混合,方法解析,类型检查等特定方式无关。

    基于高斯混合模型的增量聚类方法识别恶意软件家族

    此外,依据恶意软件家族的目的性、继承性与多样性,构建了恶意软件家族的传递闭包关系,并改进了基于高斯混合模型的增量聚类方法来识别恶意软件家族。实验证明,所提方法不仅能节省恶意软件检测的存储空间,还能显著...

    PerfTests:JavaScript 继承性能测试正确完成

    只测试最快和最流行的类系统。 例如:Prototype.js 类的速度大约是 native 的 1%,所以没有理由包含它。 这同样适用于 MooTools。 Ext.JS 不包括在内,因为它会影响其他测试的结果(来自其他作者的话)。 ##哪里...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    鉴于市场上用户的手机型号、种类、屏幕分辨率等参差不齐,传统方式根据主流系统分别开发相应的系统耗时又耗力,为了高效开发并节约开发项目成本,本文采用Android+HTML5相结合的方式进行移动端Web系统的设计研发工作...

    国内外主流的三维GIS软件

     介绍:EV-Globe具有大范围的、海量的、多源的数据一体化管理和快速三维实时漫游功能,支持三维空间查询、分析和运算,可与常规GIS软件集成,可方便快速构建三维空间信息服务系统,亦可快速在二维GIS系统完成向三维...

    wpf完全教程1-4章

     2.8 编译:将XAML与过程式代码混合使用   2.8.1 在运行时加载和解析XAML   2.8.2 编译XAML   2.8.3 XAML关键字   2.9 小结   2.9.1 抱怨1:XML太过冗长不便于输入   2.9.2 抱怨2:基于XML的...

    WPF揭秘 第四章 wpf 开发

     2.8 编译:将XAML与过程式代码混合使用   2.8.1 在运行时加载和解析XAML   2.8.2 编译XAML   2.8.3 XAML关键字   2.9 小结   2.9.1 抱怨1:XML太过冗长不便于输入   2.9.2 抱怨2:基于XML的...

    WPF揭秘 第二章 wpf 开发

     2.8 编译:将XAML与过程式代码混合使用   2.8.1 在运行时加载和解析XAML   2.8.2 编译XAML   2.8.3 XAML关键字   2.9 小结   2.9.1 抱怨1:XML太过冗长不便于输入   2.9.2 抱怨2:基于XML的...

    WPF揭秘 第三章 wpf 开发

     2.8 编译:将XAML与过程式代码混合使用   2.8.1 在运行时加载和解析XAML   2.8.2 编译XAML   2.8.3 XAML关键字   2.9 小结   2.9.1 抱怨1:XML太过冗长不便于输入   2.9.2 抱怨2:基于XML的...

    WPF揭秘 第一章 wpf 开发

     2.8 编译:将XAML与过程式代码混合使用   2.8.1 在运行时加载和解析XAML   2.8.2 编译XAML   2.8.3 XAML关键字   2.9 小结   2.9.1 抱怨1:XML太过冗长不便于输入   2.9.2 抱怨2:基于XML的...

    面向半结构化数据处理的混合本体编程-研究论文

    它结合了用于构建领域模型的声明式风格和用于处理它的命令式风格。 领域模型采用本体的形式,由一组相互关联的概念组成。 概念定义的语法允许通过将现有概念与逻辑关系链接来创建新概念。 还可以使用继承、嵌套概念...

    Windows内核安全与驱动开发光盘源码

    第11章 文件系统的过滤与监控 199 11.1 文件系统的设备对象 200 11.1.1 控制设备与卷设备 200 11.1.2 生成自己的一个控制设备 201 11.2 文件系统的分发函数 202 11.2.1 普通的分发函数 202 11.2.2 文件过滤的...

    F:F,一个鼓励代码重用的 Backbone 组件框架

    F 使用 ,这是一个 OOP 框架,可让您创建可以扩展、混合和重用的构建块。听起来很有趣?F楼克隆存储库 git clone https://github.com/lazd/F.git安装依赖 cd F/npm install用咕噜声构建 F grunt构建输出将发送到...

    Sass与Compass实战

    本书共分为10章,旨在完整...本书介绍了Sass如何通过选择器嵌套和变量来帮助避免重复,以及通过继承和混合器等特性更加高效地重用通用样式,减少重复编写工作。学完本书后,你一定能对Sass和Compass有一个全面的理解。

    市场化改革对促进中国代际流动的贡献

    市场化改革对促进中国代际流动的贡献,阳义南,,本文构建了由CGSS2008、2010、2012与市场化指数组成的混合横截面数据。实证结果表明我国仍存在显著的代际继承现象,社会经济地位的代�

    聚合物:我们原始的Web组件库

    如果您有使用较早版本的Polymer库构建的项目,我们建议您到3.0以与JavaScript生态系统实现最佳兼容性。 由于Web组件的互操作性,可以在同一应用程序中混合和匹配使用Polymer 3.0和LitElement构建的元素,因此,一旦...

    Windows内核安全驱动开发(随书光盘)

    第11章 文件系统的过滤与监控 199 11.1 文件系统的设备对象 200 11.1.1 控制设备与卷设备 200 11.1.2 生成自己的一个控制设备 201 11.2 文件系统的分发函数 202 11.2.1 普通的分发函数 202 11.2.2 文件过滤的...

    C#微软培训资料

    17.1 .Net 框架结构提供的 I/O 方式 .215 17.2 文件存储管理 .217 17.3 读 写 文 件 .222 17.4 异步文件操作 .227 17.5 小 结 .234 第十八章 高 级 话 题 .235 18.1 注册表编程 .235 18.2 在 C #代码...

    二十三种设计模式【PDF版】

    使用类再生的两个方式:组合(new)和继承(extends),这个已经在 thinking in java中提到过. 设计模式之 Proxy(代理) 以 Jive 为例,剖析代理模式在用户级别授权机制上的应用 设计模式之 Facade(门面?) 可扩展的使用...

Global site tag (gtag.js) - Google Analytics