我需要一些简单的对象,以后会变得更复杂,有许多不同的属性,所以我想到了装饰模式。 我这样看着Crockford的幂构造函数和对象增强:
//add property to object
Object.prototype.addProperty = function(name, func){
for(propertyName in this){
if(propertyName == name){
throw new Error(propertyName + " is already defined");
}
}
this[name] = func;
};
//constructor of base object
var BasicConstructor = function(param){
var _privateVar = param;
return{
getPrivateVar: function(){
return _privateVar;
}
};
};
//a simple decorator, adds one private attribute and one privileged method
var simpleDecorator = function(obj, param){
var _privateVar = param;
var privilegedMethod1 = function(){
return "privateVar of decorator is: " + _privateVar;
};
obj.addProperty("privilegedMethod1", privilegedMethod1);
return obj;
}
//a more complex decorator, adds public and private properties
var complexDecorator = function(obj, param1, param2){
//private properties
var _privateVar = param1;
var _privateMethod = function(x){
for(var i=0; i<x; i++){
_privateVar += x;
}
return _privateVar;
};
//public properties
var publicVar = "I'm public";
obj.addProperty("publicVar", publicVar);
var privilegedMethod2 = function(){
return _privateMethod(param2);
};
obj.addProperty("privilegedMethod2", privilegedMethod2);
var publicMethod = function(){
var temp = this.privilegedMethod2();
return "do something: " + temp + " - publicVar is: " + this.publicVar;
};
obj.addProperty("publicMethod", publicMethod);
return obj;
}
//new basic object
var myObj = new BasicConstructor("obj1");
//the basic object will be decorated
var myObj = simpleDecorator(obj, "aParam");
//the basic object will be decorated with other properties
var myObj = complexDecorator(obj, 2, 3);
这是在javascript中使用装饰器模式的好方法吗? 还有其他更好的方法吗?
答案 0 :(得分:9)
Wikipedia和其他网站上的Javascript中有各种各样的Decorator模式实现 - (1),(2),(3)。该模式定义为:
装饰器模式是一种设计模式,允许动态地将新/附加行为添加到现有对象。
对象扩展已经构建到语言本身中。可以轻松扩展对象,并可以随时添加属性。那你为什么要跳过篮球来实现呢?不应该这样的事情就足够了:
var person = { name: "Jack Bauer" };
// Decorated the object with ability to say a given phrase
person.say = function(phrase) {
alert(phrase);
}
// Using the decorated functionality
person.say("Damn it!");
如果要将方法应用于使用此函数创建的所有对象,请将该方法/属性添加到函数的原型中。
更新:如果您有明确定义的功能,可以根据需要混合并匹配到某些类型的对象中,那么MooTools extending方法mixing和{ {3}}行为很好地完成了对象。举一个例子,考虑一个可以调整大小,用手柄拖动并通过单击右上角的刻度标记删除的UI组件。您可能不希望使用这些行为创建每个组件,而是将所有这些行为分别定义到它们自己的对象中。然后根据需要将这些行为混合到每种类型的组件中。
var Resizable = {
...
};
var Draggable = {
...
};
var Deletable = {
...
};
var someLabel = new Label("Hello World");
// one way to do it
someLabel.implement([Resizable, Draggable, Deletable]);
// another way to do it
someLabel.implement(Resizable);
someLabel.implement(Draggable);
someLabel.implement(Deletable);
它看起来比做
之类的东西更好,更直观(对我而言)var awesomeLabel = new Resizable(new Draggable(new Deletable(someLabel)));
因为我们仍在处理一个标签,而不是一些可调整大小的,或一些可拖动的,或一些可删除的对象。另一个小问题,但仍然值得一提的是,在3或4个装饰器后,括号开始变得无法管理,特别是没有良好的IDE支持。