实际的面向对象的devise模式的例子
你在应用程序的JavaScript中使用了什么面向对象的devise模式,为什么?
随意张贴代码,即使没有正式的devise模式附加到它。
我已经写了大量的JavaScript,但我没有应用太多的面向对象的模式,我正在做什么,我相信我错过了很多。
以下是三种stream行的JavaScript模式。 由于closures,这些事情很容易实现:
- 模块模式 – 埃里克Miraglia的例子(并stream行)
- 记忆 – Oliver Steele的例子
- 柯里格 – 例如达斯汀·迪亚兹
你可能也想看看:
- Pro JavaScriptdevise模式由Ross Harmes和Dustin Diaz提供
以下是由Diaz提供的2008年Google I / O讲座,他讨论了他的书中的一些主题:
- Google I / O 2008 – expression语言的devise模式
遗产
我使用基于ExtJS 3的 inheritance的符号 ,我发现它非常接近在Java中模拟古典inheritance。 它基本上运行如下:
// 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坚持命名空间,所以上面的代码应该在窗口对象之外的自己的上下文中运行,如果你打算让你的代码作为在浏览器窗口中执行的许多并发框架/库之一运行,这是至关重要的。
这意味着窗口对象的唯一途径是通过你自己的命名空间/模块对象:
// 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构造,如接口来增强您的应用程序devise。 我的方法是增强Function.prototype
以获得一个符号沿着这些线:
var Dog = Object.extend(Animal, { bark: function() { alert('woof'); } // more methods .. }).implement(Mammal, Carnivore);
OO模式
对于Java中的“Patterns”,我只发现了Singleton模式 (非常适合caching)和Observer模式,用于事件驱动的function,比如当用户点击一个button时分配一些动作。
使用观察者模式的一个例子是:
// 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'); });
而这只是我包里的几个技巧,希望对你有用。
我build议,如果你打算走下这条道路,你读道格拉斯Crockfords使用Javascript:好部分 。 这是一本很好的书。
我是模块模式的粉丝。 这是实现可扩展,非依赖(大部分时间)框架的一种方式。
例:
框架Q
定义如下:
var Q = {};
要添加一个function:
Q.test = function(){};
这两行代码一起使用来组成模块 。 模块背后的思想是,它们都扩展了一些基本框架,在这种情况下是Q
,但不相互依赖(如果devise正确的话),并且可以以任何顺序包括在内。
在模块中,如果框架对象不存在,则首先创build框架对象(这是Singleton模式的示例):
if (!Q) var Q = {}; Q.myFunction = function(){};
这样,你可以在不同的文件中有多个模块(比如上面的模块),并以任何顺序包含它们。 它们中的任何一个都将创build框架对象,然后对其进行扩展。 无需手动检查框架是否存在。 然后,检查自定义代码中是否存在模块/函数:
if (Q.myFunction) Q.myFunction(); else // Use a different approach/method
单身模式通常对“封装”和组织的东西非常有帮助。 你甚至可以改变可访问性。
var myInstance = { method1: function () { // ... }, method2: function () { // ... } };
最简洁的方式来在JavaScript中实现一个单身人士
我真的很喜欢jQuery的方法链模式 ,允许你在一个对象上调用几个方法。 它使得在一行代码中执行多个操作变得非常简单。
例:
$('#nav').click(function() { $(this).css('color','#f00').fadeOut(); });
我非常喜欢使用jQuery插件的Decorator模式 。 编写一个自定义插件,只是转发请求并添加额外的参数和function,而不是修改插件来满足您的需求。
例如,如果您需要一直传递一组默认参数,并且需要与业务逻辑相关的稍微不同的行为,请编写一个插件,用于执行任何pre
和post
工作,以满足您的需求,并将您的默认参数,如果这些特定的参数没有指定。
这样做的主要好处是您可以更新您的库,而不用担心移植库更改。 您的代码可能会中断,但至less有可能不会。
javascript世界中有用的模式之一就是LINQ开始stream行的链式模式,也被用在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
关键词,这使得可以访问计算器function的其他公众成员。