实际的面向对象的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,而不是修改插件来满足您的需求。

例如,如果您需要一直传递一组默认参数,并且需要与业务逻辑相关的稍微不同的行为,请编写一个插件,用于执行任何prepost工作,以满足您的需求,并将您的默认参数,如果这些特定的参数没有指定。

这样做的主要好处是您可以更新您的库,而不用担心移植库更改。 您的代码可能会中断,但至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的其他公众成员。