【问题标题】:Examples of practical javascript object oriented design patterns实用的 javascript 面向对象设计模式示例
【发布时间】:2011-04-12 23:26:30
【问题描述】:

您在应用程序的 javascript 中使用了哪些面向对象的设计模式,为什么?

即使没有附加正式的设计模式,也可以随意发布代码。

我写了很多 javascript,但我没有在我的工作中应用太多面向对象的模式,我确信我错过了很多。

【问题讨论】:

  • 您可能没有像您想象的那样看过经典的 OOP。但是,您可能已经使用了原型 OOP 的功能,但从未真正意识到这一点。
  • 我确实(有时)意识到我在使用 OOP 时 - 我想更有意识地开始使用 OOP,正是因为我想更加慎重地考虑它
  • 我投票结束这个问题,因为它只是要求列出其他人在他们的代码中所做的事情。

标签: javascript jquery design-patterns oop


【解决方案1】:

以下是三种流行的 JavaScript 模式。由于closures,这些恰好很容易实现:

您可能还想查看:

以下是 Diaz 在 2008 年发表的 Google I/O 演讲,他在其中讨论了他书中的一些主题:

【讨论】:

  • 不错! curry 看起来像是一种更聪明的方式来做一些我试图做的概括。已经在使用简单形式的模块和记忆 - 但需要研究这些例子来推动我目前的做法。您最常使用哪些?
  • @ming:可能是模块模式。非常容易实现和理解,并且带有一些很酷的特性,包括命名空间和私有变量/方法。
【解决方案2】:

继承

我使用基于ExtJS 3notation for inheritance,我发现它非常接近于在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 坚持使用命名空间的观点,因此上面的代码应该在窗口对象之外的自己的上下文中运行,如果您希望您的代码作为在浏览器窗口。

这意味着访问窗口对象的唯一方法是通过您自己的命名空间/模块对象:

// 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 构造(例如接口)来增强您的应用程序设计。 My approach to these 是对Function.prototype 的增强,以便获得符合这些方面的符号:

var Dog = Object.extend(Animal, {
     bark: function() {
         alert('woof');
     }
     // more methods ..
}).implement(Mammal, Carnivore);

OO 模式

至于 Java 意义上的“模式”,我只发现 Singleton pattern(非常适合缓存)和 Observer pattern 用于事件驱动的功能,例如在用户单击时分配一些操作按钮。

使用观察者模式的一个例子是:

// 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。这是一本很棒的书。

【讨论】:

    【解决方案3】:

    我是模块模式的粉丝。它是一种实现可扩展、非依赖(大部分时间)框架的方式。

    示例:

    框架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
    

    【讨论】:

    • 这看起来非常有用。您如何在代码中使用它?感谢分享!
    • 我在最近的一个项目中使用了它,在该项目中,我为常用功能、UI 和其他两个专用机制提供了单独的 JavaScript 文件。所有文件都将函数添加到同一个框架(使用我上面显示的方法定义),并且它们像我上面所做的那样调用函数。
    • 这种技术的主要用途之一是避免污染全局命名空间。什么污染更多?一个 Q 框架变量,还是几十个函数和变量?
    【解决方案4】:

    单例模式通常对“封装”和组织内容非常有帮助。您甚至可以更改可访问性。

    var myInstance = {
      method1: function () {
        // ...
      },
      method2: function () {
        // ...
      }
    };
    

    cleanest way to implement a singleton in javascript

    【讨论】:

    • 太棒了 - 这是我一直使用的!但这只是我的 javascript OO 的范围。 ;)
    【解决方案5】:

    我真的很喜欢 jquery 的method chaining pattern,它允许你在一个对象上调用多个方法。它使得在一行代码中执行多个操作变得非常容易。

    例子:

    $('#nav').click(function() {
       $(this).css('color','#f00').fadeOut();
    });
    

    【讨论】:

    • 正确 - 同意!您以前开发过自己的自定义方法吗?
    【解决方案6】:

    我真的很喜欢带有 jQ​​uery 插件的 Decorator pattern。与其修改插件以满足您的需求,不如编写一个自定义插件来转发请求并添加额外的参数和功能。

    例如,如果您需要始终传递一组默认参数,并且您需要与业务逻辑相关的稍有不同的行为,请编写一个插件来完成 prepost 的任何必要工作如果未指定这些特定参数,则可以满足您的需要并传递您的默认参数。

    这样做的主要好处是您可以更新您的库,而不必担心移植库更改。您的代码可能会出错,但至少有可能不会。

    【讨论】:

    • 这听起来是个好主意。您是否有代码上的实际示例来进行实际扩展?即使是一个简单的例子也会对每个人都有很大的帮助。
    【解决方案7】:

    在 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关键字,这使得访问Calculator函数的其他公共成员成为可能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-12
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      • 2011-08-04
      • 2012-10-20
      相关资源
      最近更新 更多