您在应用程序的javascript中使用哪种面向对象的设计模式,为什么?
即使没有附加正式的设计模式,也可以自由发布代码。
我已经写了很多JavaScript,但是我没有在我的工作中应用很多面向对象的模式,所以我肯定会遗漏很多东西。
Answers:
以下是三种流行的JavaScript模式。这些由于闭包而易于实现:
您可能还需要签出:
以下是Diaz在2008年发表的Google I / O演讲,他在书中讨论了一些主题:
遗产
我使用了基于ExtJS 3的继承符号,我发现它的工作方式非常接近于模拟Java中的经典继承。它的基本运行方式如下:
// Create an 'Animal' class by extending
// the 'Object' class with our magic method
var Animal = Object.extend(Object, {
move : function() {alert('moving...');}
});
// Create a 'Dog' class that extends 'Animal'
var Dog = Object.extend(Animal, {
bark : function() {alert('woof');}
});
// Instantiate Lassie
var lassie = new Dog();
// She can move and bark!
lassie.move();
lassie.bark();
命名空间
我也同意Eric Miraglia坚持使用名称空间的观点,因此,上面的代码应该在window对象之外的自己的上下文中运行,如果您打算将代码作为在浏览器窗口中执行的许多并发框架/库之一运行,则这至关重要。
这意味着到达窗口对象的唯一方法是通过您自己的名称空间/模块对象:
// Create a namespace / module for your project
window.MyModule = {};
// Commence scope to prevent littering
// the window object with unwanted variables
(function() {
var Animal = window.MyModule.Animal = Object.extend(Object, {
move: function() {alert('moving...');}
});
// .. more code
})();
介面
您还可以利用更多高级OOP构造(例如接口)来增强应用程序设计。我对此的处理方法是增强Function.prototype
,以便按照以下方式获得注释:
var Dog = Object.extend(Animal, {
bark: function() {
alert('woof');
}
// more methods ..
}).implement(Mammal, Carnivore);
OO模式
至于Java的“模式”,我发现它仅用于Singleton模式(非常适合缓存)和Observer模式用于事件驱动的功能,例如在用户单击按钮时分配一些操作。
利用观察者模式的一个例子是:
// Instantiate object
var lassie = new Animal('Lassie');
// Register listener
lassie.on('eat', function(food) {
this.food += food;
});
// Feed lassie by triggering listener
$('#feeding-button').click(function() {
var food = prompt('How many food units should we give lassie?');
lassie.trigger('eat', [food]);
alert('Lassie has already eaten ' + lassie.food + ' units');
});
那只是我的OO JS包中的几个技巧,希望它们对您有用。
如果您打算走这条路,我建议您阅读Douglas Crockfords Javascript:The Good Parts。这是一本精采的书。
我是Module Pattern的粉丝。这是一种实现可扩展的,非依赖的(大多数情况下)框架的方法。
例:
框架Q
定义如下:
var Q = {};
要添加功能:
Q.test = function(){};
这两行代码一起用于形成模块。在这种情况下Q
,模块背后的思想是它们都扩展了一些基本框架,但彼此之间并不依赖(如果设计正确),可以以任何顺序包含在内。
在模块中,首先创建框架对象(如果不存在)(这是Singleton模式的示例):
if (!Q)
var Q = {};
Q.myFunction = function(){};
这样,您可以在单独的文件中拥有多个模块(如上面的模块),并以任何顺序包含它们。他们中的任何一个都会创建框架对象,然后对其进行扩展。无需手动检查框架是否存在。然后,检查自定义代码中是否存在模块/功能:
if (Q.myFunction)
Q.myFunction();
else
// Use a different approach/method
Q
框架变量,还是数十个函数和变量?
单例模式通常对于“封装”和组织内容非常有用。您甚至可以更改可访问性。
var myInstance = {
method1: function () {
// ...
},
method2: function () {
// ...
}
};
我真的很喜欢带有jQuery插件的Decorator模式。与其修改插件来满足您的需求,不如编写一个自定义插件来转发请求并添加其他参数和功能。
例如,如果你需要传递一组周围所有的时间默认参数,你需要稍微不同的行为关系到业务逻辑,写一个插件,做什么pre
和post
工作是必要的,以满足您的需求,并通过您的默认参数如果未指定这些特定参数。
这样做的主要好处是您可以更新库,而不必担心移植库更改。您的代码可能会中断,但至少有可能不会中断。
在javascript世界中,有用的模式之一是链模式,该模式最初由LINQ流行,并在jQuery中使用。
这种模式使我们能够以链接的方式调用类的不同方法。
这种模式的主要结构是
var Calaculator = function (init) {
var result = 0;
this.add = function (x) { result += (init + x); return this; };
this.sub = function (x) { result += (init - x); return this; };
this.mul = function (x) { result += (init * x); return this; };
this.div = function (x) { result += (init / x); return this; };
this.equals = function (callback) {
callback(result);
}
return this;
};
new Calaculator(0)
.add(10)
.mul(2)
.sub(5)
.div(3)
.equals(function (result) {
console.log(result);
});
该模式的关键思想是this
关键词,它使访问计算器功能的其他公共成员成为可能。