JavaScript:将行为插入对象并轻松删除这些行为
在JavaScript中,我想在长时间运行的应用程序中实例化一个对象。对象应该允许它自己被mixin扩充。有一些设计限制: mixin可以覆盖现有的方法 mixin可以提供新的方法 给定的mixin方法应该能够引用super,从而允许跨越多个mixin的类似命名行为通过管道传输到一起 从对象中移除mixin应该不会比添加mixin更难 我想把mixin推到对象中。也就是说,我希望不要包装/装饰对象,因为它过期了对原始对象的引用。 在JS中,mixin通常将其方法直接复制到对象上。如果您不想轻易地拔掉新行为,这是很好的。其思想是,这些行为应该可以随时轻松添加或删除,因为应用程序可能会无限期地运行,而使用对象来添加行为并不会使以后删除它变得整洁和容易 我泛指的是“混合”。其主要思想是,对象可以插入或拔出可以通过管道连接在一起的行为;机制本身就不那么重要。你们中一些可能熟悉的人知道这是多么有用JavaScript:将行为插入对象并轻松删除这些行为,javascript,design-patterns,rack,Javascript,Design Patterns,Rack,在JavaScript中,我想在长时间运行的应用程序中实例化一个对象。对象应该允许它自己被mixin扩充。有一些设计限制: mixin可以覆盖现有的方法 mixin可以提供新的方法 给定的mixin方法应该能够引用super,从而允许跨越多个mixin的类似命名行为通过管道传输到一起 从对象中移除mixin应该不会比添加mixin更难 我想把mixin推到对象中。也就是说,我希望不要包装/装饰对象,因为它过期了对原始对象的引用。 在JS中,mixin通常将其方法直接复制到对象上。如果您不想轻易地
var tim = new Person('Tim'); //at 12:00pm
tim.eat() //at 12:00pm -- native Person behavior
tim.addBehavior(husband) //at 12:00pm
tim.kissWife() //at 12:00pm -- husband behavior
tim.addBehavior(father) //at 12:00pm
tim.addBehavior(hungry) //at 12:00pm -- augments the native eat behavior
tim.addBehavior(bowler) //at 5:00pm
tim.bowl() //at 5:00pm
tim.performDailyDuties() //at 5:00pm -- includes husband and father duties
tim.removeBehavior(bowler) //at 5:00pm -- easily remove behavior
tim.bowl() //at 5:01pm -- error!
tim.kissWife() //at 5:01pm
我不想
var husbandTim = new Husband(tim)
var bowlerTim = new Bowler(husbandTim)
…因为这使得很难消除一个特定的行为。另外,所有提到蒂姆的地方呢。这些地方不会意识到新的行为
不幸的是,JS并没有提供我所知道的任何东西来简化这个过程。ES6将提供一个代理来实现这一点,但我想知道我是否错过了一个更简单的方法
什么样的设计模式或机制可以使添加插件行为变得容易,而这些行为在以后也同样容易删除?有没有框架可以这样做?我不久前创建了一个ES5继承库,名为,它允许您向对象添加mixin并调用Overwrited方法。例如:
var PersonObject = {
init : function(name) {
this.name = name;
},
fullName : function() {
return this.name;
}
};
Proto.mixin({
fullName : function() {
return 'My name is: ' + this._super();
}
}, PersonObject);
// Create a plain object without calling the constructor
var instance = Object.create(PersonObject);
instance.name = 'Dude';
console.log(instance.fullName()); // 'My name is: Dude'
我发现,如果你小心地为什么创建混合,它实际上工作得很好。我从不需要删除mixin,但它应该像在添加之前存储对原始方法的引用一样简单:
var PersonObject = {
init : function(name) {
this.name = name;
},
fullName : function() {
return this.name;
}
};
var backup = {
fullName: PersonObject.fullName
};
Proto.mixin({
fullName : function() {
return 'My name is: ' + this._super();
}
}, PersonObject);
// Create a plain object without calling the constructor
var instance = Object.create(PersonObject);
instance.name = 'Dude';
console.log(instance.fullName()); // 'My name is: Dude'
// Restore old mixin
PersonObject.fullName = backup.fullName;
var instance = Object.create(PersonObject);
instance.name = 'Dave';
console.log(instance.fullName()); // 'Dave'
所以,你所需要做的就是将该功能包装成更通用的功能。在我所研究的大多数应用程序中,能够拔下混音器并不是一个很重要的需求。但是,我目前确实需要一个应用程序。不幸的是,大多数语言并没有使分解变得简单,它们应该这样做。如果JavaScript不使用单个原型,而是允许多个原型和多个继承,那么它可以很容易地适应这种情况。我会调查你的想法。感谢您的回复。在JS中进行一般性的分解将非常困难,至少在大多数实现中是如此。您必须。t尝试函数,然后沿着_超级链查看是否有匹配项。然后不知何故把它从链条上扯下来。但是如果你有任何想法,我很乐意考虑把它添加到图书馆。但正如你所说,我也从来没有遇到过需要删除它的情况。我使用代理,它工作得很好。我只是不喜欢有必要委托代理人。大多数应用程序不需要使用unmix的原因是,对象通常只存在一小会儿,以便完成工作;没有多少东西是长期保存的。认为我们扮演的角色是暂时的。当有丈夫行为的人离婚时,这种行为应该消失。