At some points, any developer will read something about loose-coupling and the Law of Demeter.

It is usually happening when you are writing code that becomes a bit larger and you start to have difficulties to scale it up, maintain it, read it, test it, and so on. The idea is very simple, each component should work on its own, responsible for its own task, be encapsulated, and while begin part of something bigger, should not know about the other components (not having a reference to them).

You usually have 2 problems to solve to achieve this:
1. find a way so the component is getting data to do its job
2. find a way so the component can tell other components that something has been done

There’s tons of way of solving the first one, I talked about one of them in a previous post: injection with infuse.js.

And to solve the second problem, the Observer Pattern is usually the way, also called “publishing-subscribing”.

Let me quote Addy Osmani again:
“The motivation behind using the observer pattern is where you need to maintain consistency between related objects without making classes tightly coupled. For example, when an object needs to be able to notify other objects without making assumptions regarding those objects.”

I’ve kind of always been concerned with that one, as in the best world, you don’t want to add framework code in a view or a model component that should be fully re-usable, and re-usable everywhere, and written in pure plain javascript where possible.

There’s one Observer Pattern that is part of the Dom specification: the Event model (Dom 4 Event specs seems on its way too).

It would be a very good thing to use something standard as an Observer Pattern but there’s 2 problems with that one:
1. cross-browsing issues
2. need a DOM

I’ve extracted the observer pattern used in the soma.js framework so it is easily re-usable everywhere.

It is called soma-events, and provides a wrapper function to create native custom events and solve cross-browsing issues, and a custom dispatcher so the exact same API can be used without the DOM.

As a very quick overview, it would look like this:

var EventTypes = {
    START: "start"
}
var Application = function() {
    var model = new Model();
    dispatcher.dispatchEvent(new Event(EventTypes.START, {myStuff:"myStuff"}));
};
var Model = function() {
    dispatcher.addEventListener(EventTypes.START, function(event) {
        console.log("application started with:", event.params.myStuff);
    });
};
var app = new Application();

The dispatcher variable in this example can be both a custom dispatcher (EventDispather), or just a DOM Element.

More info and example on the Github readme:
https://github.com/soundstep/soma-events

Quick install (works also with node.js):

npm install soma-events

Share and Enjoy!