Using Class.Occlude to Create Singletons

Monday, July 13th, 2009 @ 10:34 am | filed under: Best Practices

In my last article I talk about using an instance of Events to allow for loose coupling of functionality to limit dependencies as well as the use of singletons. There was a comment at the bottom of that article that I thought worth sharing and expounding upon:

I’ve been using Class.Occlude and occluding to document.body when I need a singleton. Works like a charm. – Kris Wallsmith

I thought this was a great idea and thought I’d explain what he means for those of you perhaps unfamiliar with Class.Occlude.

What Class.Occlude Does

Class.Occlude allows you to define a class that is tied to a DOM element (as most are) and to prevent that class from creating more than one instance for that DOM element. If you created a class that, say, validated a form, and you wanted to ensure that the user (the JavaScript user – not a site visitor) of your class didn’t attach two instances of that validator to the same form twice, as doing so would result in, say, a state where it was impossible to submit the form, you could use Class.Occlude to ensure that even if two instances of the form validator were created, only one would do anything. Indeed, the second time you tried to instantiate the validator class you would just be returned the first one. Here’s what it looks like:

var FancyFormValidator = new Class({
  Implements: Class.Occlude,
  property: 'FancyFormValidator',
  initialize: function(form) {
    this.element = $(form);
    if (this.occlude()) return this.occluded;
    //...the rest of  your awesome validation logic
  }
});
var fancyValidator = new FancyFormValidator($('myform'));
var fancyValidator2 = new FancyFormValidator($('myform'));
//fancyValidator === fancyValidator2

Using Class.Occlude to Create Singletons

So what Kris does (per his comment) when he wants an instance of a class but wants to ensure that there is only ever one instance, he occludes the document body. This means that even if you try and create a new instance of that class, if you’ve already created one, you’ll be returned the existing one.

For example:

var SingleFoo = new Class({
  Implements: Class.Occlude,
  property: 'SingleFoo',
  initialize: function(arg1, arg2, etc) {
    this.element = $(document.body);
    if (this.occlude()) return this.occluded;
    //the rest of your stuff goes here
 }
});
var foo1 = new SingleFoo(a1, a2, etc);
var foo2 = new SingleFoo(b1, b2, etc);
//foo1 === foo2

A clever solution, if you ask me.

7 Responses to “Using Class.Occlude to Create Singletons”

  1. Martin Says:

    I don’t really get the last part. Can you give a document body code example?

  2. Aaron N. Says:

    @Martin – Yep. I’ve updated the post with an example.

  3. Martin Says:

    Ahh, I see. Thanks!

  4. adamnfish Says:

    Does your first example clas need to implement Class.Occlude?

  5. Aaron N. Says:

    @adamfish oh, duh! Yeah. Nice catch. I’ve updated the example.

  6. tibolan Says:

    I use something like that in my application code:

    var mySingletonClass = new Class(...);
    mySingletonClass = new mySingletonClass;

    The action just destroy the constructor of mySingletonClass, then you got a easy doin’ Singleton.

    Am I wrong ?
    Could this “trick” generate problem ?
    Or it’s just a OOP failure ?

    Thank you for this interesting post !

  7. Aaron N. Says:

    There’s no value in doing that – you could just declare your object and be done with it. The only value in making it a class is so you could extend it or implement changes into it, which your example would preclude.