81

What object oriented design patterns do you use in your application's javascript, and why?

Feel free to post code, even if there is no formal design pattern attached to it.

I have written plenty of javascript, but I have not applied much object orientated patterns to what I am doing, and I am sure i am missing a lot.

meow
  • 27,476
  • 33
  • 116
  • 177
  • You probably have not not seen classical OOP in the sense that you might think. However, you have probably utilized features with prototypical OOP and just never really realized it. – dave Sep 16 '10 at 00:24
  • I actually do (sometimes) realize when i am using OOP - i want to start using OOP much more consciously, precisely because i want to be much more deliberate about it – meow Sep 16 '10 at 03:14
  • I'm voting to close this question as off-topic because it's just asking for a list of stuff other people do in their code. – Almo Feb 12 '18 at 21:34

7 Answers7

54

The following are three popular JavaScript patterns. These happen to be easily implementable because of closures:

You may also want to check out:

The following is a Google I/O talk from 2008 presented by Diaz, where he discusses some topics from his book:

Daniel Vassallo
  • 337,827
  • 72
  • 505
  • 443
  • nice! curry looks like a way smarter way to do some of the generalization i was trying to do. already using simple forms of module and memoization - but need to study these examples to push how i currently do it. Which ones do you use the most? – meow Sep 16 '10 at 01:12
  • @ming: Probably, it's the module pattern. Very easy to implement and to understand, and it comes with some cool features, including namespacing and private variables/methods. – Daniel Vassallo Sep 16 '10 at 01:20
26

Inheritance

I use a notation for inheritance that is based on ExtJS 3, which I find works pretty close to emulating classical inheritance in Java. It basically runs as follows:

// 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();

Namespaces

I also agree with Eric Miraglia on sticking to namespaces so the code above should be run within its own context outside the window object, this is critical if you intend your code to run as one of many concurrent frameworks / libraries executing in the browser window.

This means that the only way to the window object is via your own namespace / module object:

// 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

})();

Interfaces

You can also make use of more advances OOP constructs such as interfaces to enhance your application design. My approach to these is to enhance the Function.prototype in order to get a notation along these lines:

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

OO Patterns

As for 'Patterns' in the Java sense, I've only found use for the Singleton pattern (great for caching) and the Observer pattern for event-driven functionality such as assigning some actions when a user clicks on a button.

An example of utilising the Observer Pattern would be:

// 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');
});

And thats just a couple of tricks in my bag of OO JS, hope they are useful to you.

I recommend if you intend to go down this road that you read Douglas Crockfords Javascript: the Good Parts. Its a brilliant book for this stuff.

Steven de Salas
  • 20,944
  • 9
  • 74
  • 82
20

I am a fan of the Module Pattern. It's a way of implementing extensible, non-dependent (most of the time) frameworks.

Example:

The framework, Q, is defined like this:

var Q = {};

To add a function:

Q.test = function(){};

These two lines of code are used together to form modules. The idea behind modules is that they all extend some base framework, in this case Q, but are not reliant on each other (if designed correctly) and can be included in any order.

In a module, you first create the framework object if it does not exist (which is an example of the Singleton pattern):

if (!Q)
    var Q = {};

Q.myFunction = function(){};

That way, you can have multiple modules (like the one above) in separate files, and include them in any order. Any one of them will create the framework object, and then extend it. No manual need to check if the framework exists. Then, to check if a module/function exists in custom code:

if (Q.myFunction)
    Q.myFunction();
else
    // Use a different approach/method
Chris Laplante
  • 29,338
  • 17
  • 103
  • 134
  • 1
    This looks extremely useful. how are you using this in your code? thanks for sharing! – meow Sep 16 '10 at 01:14
  • I used it on a recent project I did where I had separate JavaScript files for the common functions, UI, and two other specialized mechanisms. All the files added functions to the same framework (defined using the method I showed above) and they called the functions like I did above. – Chris Laplante Sep 16 '10 at 20:57
  • One of the main uses for this type of technique is avoiding pollution of the global namespace. What pollutes more? A single `Q` framework variable, or dozens and dozens of functions and variables? – Chris Laplante Sep 16 '10 at 20:58
6

The singleton pattern is often very helpful for 'encapsulation' and organization stuff. You can even change accesibility.

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

cleanest way to implement a singleton in javascript

Community
  • 1
  • 1
Gordon Gustafson
  • 40,133
  • 25
  • 115
  • 157
  • awesome - This is the one i use all the time! But that is just about the extent of my javascript OO. ;) – meow Sep 16 '10 at 00:58
4

I really like jquery's method chaining pattern, allowing you to call several methods on one object. It makes it really easy to perform several operations in a single line of code.

Example:

$('#nav').click(function() {
   $(this).css('color','#f00').fadeOut();
});
GSto
  • 41,512
  • 37
  • 133
  • 184
  • right - agreed! have you developed your own custom methods that work these way before? – meow Sep 16 '10 at 01:06
3

One of useful patterns in javascript world is chaining pattern which is made popular by LINQ at first place, and also is used in jQuery.

this pattern enables us to call different methods of a class in chaining manner.

the main structure of this pattern would be as

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);
    });

the key idea of this pattern is this key word, which makes possible accessing to other public member of Calculator fucntion.

Matrix Buster
  • 299
  • 3
  • 9
3

I really like the Decorator pattern with jQuery plugins. Rather than modifying plugins to meet your needs, write a custom plugin that just forwards requests and adds additional parameters and functionality.

For example, if you need to pass a set of default arguments around all the time, and you need slightly-different behavior that ties into business logic, write a plugin that does whatever pre and post work is necessary to suit your needs and passes your default arguments if those particular arguments aren't specified.

The main benefit of this is that you can update your libraries and not worry about porting library changes. Your code might break, but there's at least the chance that it won't.

Stefan Kendall
  • 66,414
  • 68
  • 253
  • 406
  • This sounds like a great idea. Do you have an actual example on the code to do the actual extending? Even a simple example will help everyone greatly. – meow Sep 16 '10 at 01:15