Photo credit:

Event driven programming (in javascript)

Ever since I began programming event based a couple of years ago, I've found myself using it more and more. Now its my main approach to almost all javascript projects, both on the client and on the server (on node). Here is a quick overview over the approach itself and why it fits so nicely with web projects.

First lets define what event driven programming is (or my what I mean by it):

Event driven programming follows mainly a publish-subscribe pattern, ie a class (as an example) communicates with another class with events, not by calling methods directly.

The main advantages are:

  • Loose coupling, i.e. you can remove or add features without breaking your core.
  • Flexibility - since you have loose coupling, its easy to adapt feature for different targets.
  • Seamless communication between client and server - you can use events for communicating between them as well. The biggest disadvantages might be:

  • Harder do debug - An event might be sent but you don't now who listens to it

  • Harder to follow - Same as above, specially for someone new to a project I firmly believe the advantages overweight the disadvantages, specially since some disadvantages can be overcome with better debugging tools.

Want to Learn How to Control the World with JavaScript? Read this

Basics

The best way to demonstrate how an event driven solutions differs from a traditional solutions is to illustrate it like this:

Pretend you have two classes. Foo and Bar, with the following definitions:

// Foo is a class with a public method called lorem which prints our a message as an alert when called.
var Foo = function(){
    this.lorem = function()
    {
        alert("HELLO FOO");
    }
};

// Bar is a class that when instantiated creates an instance of Foo and calls lorem.
var Bar = function(){
    var foo = new Foo();
    foo.lorem();
};
Now if we wrote the pre using events, we would write something like this instead (where myEventSystem could be [nunt](http://nunt.onezerozeroone.com/) - created for that sole purpose, jQuery - by using their event mechanism, or any other):
var Foo = function(){

    myEventSystem.on("lorem.event", lorem); // listen to the event and set a callback

    function lorem()
    {
        alert("HELLO FOO");
    }

}

// Bar is a class that when instantiated creates an instance of Foo and calls lorem.
var Bar = function(){
    var foo = new Foo();
    myEventSystem.send("lorem.event");
};
This example illustrates the difference, but it might be difficult to see the advantages with such an abstract example. Lets take a more concrete example. ### Something more realistic As I mentioned above, the flexibility and loose coupling make it perfect for solutions that evolve over time. Since most projects, particularly web projects, tend to follow that path, its easy to illustrate how this can be used to our advantage. Here is a quick example: Pretend that you have created an ajax driven (or even better, web-socket driven) web shop. Every time you click on a products "add to cart" the cart is updated. Lets illustrate: ### The traditional approach First we have our base add to cart action.
function addToCart(productId){
    cart.add(productId);
}
Somewhere else in your solution you have a cart class that talks to the backend in someway and has a method called _add()_. Now suppose that you want to add some kind of notification so the user knows that something is being added to the cart.Then, when the ajax call is done, you want to show something else. We'll modify our pre to add the new feature:
function addToCart(productId)
{
    notifications.show("Adding product " + productId);
    cart.add(function(){
        notifications.show("Added product " + productId + " to cart");
    });
}

Easy. But:

The disadvantages of this approach is that you have a hard coded connection between you cart and your notifications system. If you, for some reason, don't want to use the notification system any more, or want to remove it for a specific target, then you have to change your pre again. Or have another version for that target in mind.

Event driven

With this approach, we won't have any hard coded connections between classes. First, lets assume you have an event based system that can subscribe and publish. I usually use one called nunt, that I've written to make things easier. The first part might look like this:

function addToCart(productId){
    nunt.send("cart.add", {id: productId});
}
So far, almost the same as above. Even in this solution you have a class for the cart. The only difference being that it listens to the event "cart.add" and calls its private method add when someone sends that event.

Now we want to add the notification feature. Unlike the traditional approach, we don't need to alter the original pre. Instead, we add just add new listeners in the notification class (or you could separate this as well):

nunt.on("cart.add", function(event){
    show("Adding product " + event.id);
});

nunt.on("cart.added", function(event){ show("Added product " + event.id + " to cart"); });

In this example the add method in the cart class will send the "cart.added" class when its done, instead of calling a callback as in the traditional approach.

What we have done here is a much more flexible solution, allowing us to remove the notifications just by removing this specific feature. If you put this into a separate javascript file, its as simple as not loading the file. If the file isn't loaded, the listeners aren't set and nothing will happen, i.e. you have removed a feature without breaking anything else. You could also replace it with another kind of notification system more suitable for your target.

For me, this is a killer approach. Easy to adapt and easy to extend or modify. Last, and this is what makes it event better, if you use the same approach on the server and can communicate with the same kind of events, then you have one event eco-system that communicates in one way. You can have one mindset for all communication, instead of thinking one way for the server and one for the client.

But even without the server in mind, this makes it a very suitable way for producing the kind of solutions (the always-evolving kind) that at least we create almost all the time.

Next time, I'll be writing about the server/client event system I mentioned above. It's an ever more exiting way of event driven programming. And in my opinion why nodejs is one of the best things that has happened to the web developing community.