Module pattern

5 views
Skip to first unread message

Nickolay Platonov

unread,
Dec 28, 2010, 4:45:51 AM12/28/10
to joose-js
I thought I'll share this JXND pattern:

Module('ShareBoard.Model.Board', {
 
    use            : [
        'Syncler',
        'Syncler.Topic.UUID',
        'ShareBoard.Model.Board.View'
    ],
   
body : function (module) {

    Class('.ShareBoard.Model.Board', {
       
        does            : [
            Syncler.Topic.UUID
        ],
       
        has : {
            elementsByUUID  : Syncler.I.Object,
        },
     
        methods : {
            ...
        }
    })
}})


Its useful, when you need to use something, declared in another module, in the *class declaration* (not in the class methods).
In this case its a new initializer `Syncler.I.Object`. This initializer is declared in the 'Syncler' module and won't exist yet, if we would go
with "usual" class declaration:

Class('.ShareBoard.Model.Board', {
   
    use            : [
        'Syncler'
    ],
   
    does            : [
        'Syncler.Topic.UUID'
    ],
   
    has : {
        elementsByUUID  : Syncler.I.Object, // too early to use this initializer - `Syncler` is still being loaded
    },
   
    methods : {
        ...
    }
})

Note the leading dot in the name of the class inside of `body` - it switch the namespace of the class to top (without it, a new class
will have name `ShareBoard.Model.Board.ShareBoard.Model.Board`). This declaration is not perfect as we have to violate the DRY and probably will be
improved.

Of course if you only need to use the depended modules in the methods of your class, this pattern does not provide any advantages and just is more verbose.

Another interesting implication from this pattern is that it could be elaborated to the "commonjs" like module system, which doesn't like the global
identifiers for modules.

If we'll pass the dependencies as the 2nd argument to the `body`:

Module('ShareBoard.Model.Board', {
 
    use            : [
        'Syncler',
        'Syncler.Topic.UUID',
        'ShareBoard.Model.Board.View'
    ],
   
body : function (module, deps) {

    return module.Class({
       
        does            : [
            deps.Syncler.Topic.UUID
        ],
       
        has : {
            elementsByUUID  : deps.Syncler.I.Object
        },
       
        methods : {
            ...
        }
    })
}})

then we'll receive a "namespace-less" module system :)
Reply all
Reply to author
Forward
0 new messages