[ 4 posts ]

Peter Foti

  • Username: Fotiman
  • Joined: Thu Sep 17, 2009 10:09 am
  • Posts: 128
  • Offline
  • Profile
Tags:

Creating a singleton that can be extended with Plugins

Post Posted: Fri Nov 12, 2010 10:36 am
+0-
I'm trying to create an object with some specific requirements:
1. The object must be a singleton. There can be only 1 instance of the object, and it will be fetched via a "getInstance" method
2. The object will be an event target and have events of its own
3. It can only be initialized once.
4. This object can have certain other features plugged-in

For example, usage would probably be something like this:

var mySingletonObject1 = Y.MYOBJECT.getInstance();
var mySingletonObject2 = Y.MYOBJECT.getInstance(); // gets a reference to the same object
mySingletonObject1.init({/* config */});
// any additional calls to init will be ignored

The resulting code would probably start with something like this:
Code:
YUI.add('MYOBJECT', function (Y) {
    Y.MYOBJECT = (function () {
        // private constructor
        function _MYOBJECT() {}
        return {
            getInstance: function () {
                if (!instance) {
                    instance = new _MYOBJECT();
                }
                return instance;
            }
        };
    });
});


I think then I could do:
Code:
_MYOBJECT.NAME = "MYOBJECT";
_MYOBJECT.ATTRS = {};
Y.extend(_MYOBJECT, Y.Base, {
    initializer: function (cfg) { /* */ },
    destructor: function () { /* */ }
});

And call the superclass.constructor from within my private constructor.

So far, I think this gives me the first 2 requirements. I don't think I could really make use of the Base "ATTRS" because I won't have the attributes when the instance is created unless I modify the getInstance method to take config parameters and pass them to "new _MYOBJECT()", but that could be messy. As for only initializing it once, that's easy enough... I would just have a private boolean flag that gets set to true when an "init" method (not shown) gets called. And as for being able to add plug-ins to this object, since I've extended Y.Base, would I do something like this:

var myObject = Y.MYOBJECT.getInstance();
myObject.plug(myPluginClass);

Does this seem a reasonable approach so far?

Satyen Desai

YUI Developer

  • Username: sdesai
  • Joined: Tue Dec 09, 2008 4:17 pm
  • Posts: 302
  • GitHub: sdesai
  • Gists: sdesai
  • YUI Developer
  • Offline
  • Profile

Re: Creating a singleton that can be extended with Plugins

Post Posted: Mon Nov 15, 2010 1:11 pm
+0-
Hey Peter,

If you're still waiting for feedback: In general it seems fine. I think your solution is implying a few additional "requirements":

a) You plan to use the Attribute infrastructure for your _MYOBJECT class [ which is a reason to have Base involved ]
b) You'd like to allow for possibility of something extending _MYOBJECT in the future [ which is a strong reason to have Base involved ]
c) You find maintenance value in the consistent/standardized lifecycle support [ which is a reason to have Base involved ]

If the above aren't true, then arguably you could just augment an object literal with Event Target and Plugin Host (I believe that should work) and return it in your getInstance() call.

The only other pieces of feedback I had were:

1) If it does end up being a Base based object, then you'll need to pick some method other than "init" to initialize your instance (that's what Base uses on construction). However I'm not sure why you'd want users to init the instance, if you're already constructing it for them in your getInstance call. I'd expect a method called getInstance, to return a fully functional instance which is ready to use. It may be something which you want to fill out lazily, but in that case, it seems like there's probably a more meaningful name which makes sense in relation to whatever specific functionality MYOBJECT is providing (e.g. Y.WidgetManager.layoutWidgets()).

2) You can simplify the actual implementation - since you're already inside your YUI.add function callback. You don't need to create an anonymous (invoked) function to create Y.MYOBJECT, or _MYOBJECT, unless you're really trying to prevent other code in the YUI.add function from reaching _MYOBJECT.

Hope that helps,
Satyen

Peter Foti

  • Username: Fotiman
  • Joined: Thu Sep 17, 2009 10:09 am
  • Posts: 128
  • Offline
  • Profile

Re: Creating a singleton that can be extended with Plugins

Post Posted: Mon Nov 15, 2010 2:17 pm
+0-
Thanks for the feedback (much appreciated).

I don't really care so much about the Attribute infrastructure (at least not yet). I'm more concerned about the event handling and plugin capabilities. Extending Base seems like the easiest approach (and I'm not sure yet if/how I will use Attributes, but I like to have that option). Here's where I'm at currently:

I'm using the YUI Builder. I have code in multiple files:
myobject.js (the core object)
myplugin.js (plugin code, but still "core")

The code in myplugin.js is really also "core" functionality, but deserves it's own "namespace". For example, Y.MYOBJECT.MyPlugin.foo(). The builder code wraps these files in a YUI.add. myobject.js does everything I listed in my first post, and then the code in myplugin.js (which is also wrapped in the YUI.add) does something like:

Code:
function myPlugin() {}
myPlugin.NS = "MyPlugin";
myPlugin.prototype = {
    foo: function () {}
};
(Y.MYOBJECT.getInstance()).plug(myPlugin);


And I may want to add more "plugins". Perhaps this is not a good approach? In addition, I expect other plugins may be added outside of the YUI.add().

Actual usage might look something like:
Code:
var myObject = Y.MYOBJECT.getInstance();
myObject.plug(anotherPlugin);
myObject.start(/* page specific configuration */);
myObject.MyPlugin.foo();
myObject.AnotherPlugin.bar();


As for simplifying the implementation, I need to create some "private" variables/methods (not shown in the original example), and I *do* want to ensure that no code outside of the Y.MYOBJECT = () has direct access to those variables. So that's why it's structured the way it is.

Thanks again.

Peter Foti

  • Username: Fotiman
  • Joined: Thu Sep 17, 2009 10:09 am
  • Posts: 128
  • Offline
  • Profile

Re: Creating a singleton that can be extended with Plugins

Post Posted: Thu Nov 18, 2010 1:00 pm
+0-
I'm giving this a little more thought, and I'm wondering if perhaps my approach using Plugins is not quite correct. That is, perhaps I need to explore the concept of "submodules" instead. Is there documentation on that? I only see a vague reference to submodules on this page:
http://developer.yahoo.com/yui/3/yui/

Thanks.
  [ 4 posts ]
Display posts from previous:  Sort by  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum