Ruff 驱动的一个基本设计原则是,只做基本功能。比如,灯的驱动只提供开关的函数,以及一个查询方法。$('#led').turnOn();
$('#led').turnOff();
$('#led').isOn();
但是,如果你有扩展需求该怎么办?比如,我希望有个 toggle 函数:当灯亮时,关掉它,如果灯关着,则打开它。
使用 extend
在 Ruff 里面,每个设备对象都有一个 extend
函数,用来扩展设备对象本身:$('#led').extend({
toggle: function() {
if (this.isOn()) {
this.turnOff();
} else {
this.turnOn();
}
}
});
传给 extend
是一个普通 JavaScript 对象,其中定义的函数会直接挂载在设备对象上,所以,这里可以使用 this
访问设备对象的函数。
定义 trait
toggle 是一个常见的函数,可以在很多的设备对象上都可以使用。如果我们想把它当做一个通用的函数,在多个项目中使用,我们把它定义成一个模块。但是,如何才能保证使用目标对象上有必需的函数呢?我们可以把它定义成一个 trait
。
trait 是一个常见的语言特性,用于扩展对象行为。Ruff 的 SDK 里提供了对 trait
的支持。
在这个例子里面,我们需要定义一个 trait
,它有一个 toggle
函数,并且需要对象上有 turnOn
、turnOff
以及 isOn
函数。
我们可以这样定义 toggle 的 trait,var trait = require('trait');
var ToggleTrait = trait({
toggle: function() {
if (this.isOn()) {
this.turnOff();
} else {
this.turnOn();
}
},
turnOn: trait.required,
turnOff: trait.required,
isOn: trait.required
});
trait
的参数一个是普通的 JavaScript 对象,其中,
- 普通的 JavaScript 函数会成为一个目标对象的成员函数
- 标记为
trait.required
的函数,则用来检查目标对象是否包含该函数
有了这个 trait
,就可以用它扩展设备对象,extend
方法是支持 trait
的:$('#led').extend(ToggleTrait);
如果设备对象不包含必需的方法,则会报错。
我们也可以把这个 trait 做成一个独立的模块发布到 Rap 软件仓库。