Before I begin, I want to be clear. I’m writing this as a means to help me cement my understanding. I am not an expert. I’m learning. I expect to make mistakes, and I expect my readers to call me out on it. If in the end we all learn something together, then I think this process is worth while!
Addy describes the Module pattern like so:
The Module pattern was originally defined as a way to provide both private and public encapsulation for classes in conventional software engineering.
And then progressively adding more and more…
Consider a web application that interfaces with both Facebook and Twitter. You write a function for Twitter called getLatest that fetches the latest Tweets about Paris Hilton. (And why wouldn’t you do that?) You then write code to get the latest status updates from your friends on Facebook. What should we call that? Oh yeah – getLatest!
This isn’t something you couldn’t handle, of course, but the point is, design patterns were built for the sole purpose of helping you solve problems. In this case, the module pattern is one example of a solution that helps you organize your code. Let’s look at a full example of this.
I’ve created a simple web application that lets users keep a diary. For now the functionality is simple – you can see your past entries, write new ones, and view a particular entry. This web application is going to make use of WebSQL, which does not work in Firefox or IE! This is intentional and I plan to address this in a later blog entry. You can demo this (again, please use Chrome, and again, keep in mind there is a reason why I’m not handling multiple browsers) by going here:
This works. But – my gut is telling me that this file is messy. When I see something wrong, I’m not sure where to look since everything is mixed up together. In the paragraph above I described most of my functionality as falling into three main areas. I’ve decided that I’d like to take database stuff and abstract it into a module.
The basic structure of code using the Module pattern can be defined like so:
Raise your hand if you find that syntax confusing. I know I did. Now it makes sense to me. But for a long time it just felt… weird. I had a mental block accepting the form of this code for a long time. I’m not ashamed to admit it.
For me, it helped if I backed up a bit and looked at it like so:
Ok, that makes sense. I’m basically saying the variable someModule is equal to whatever in the heck gets done inside my parentheses. Ok, so what in the heck is happening there…
Ok, so we’re creating a function and running it. Immediately. Ok, so whatever the function returns – that’s what will be passed to someModule. Here is where things get interesting. Let’s put some code in this module.
The code for this module comes from Addy’s example. The variable, counter, is a private variable. Why? Because it isn’t actually returned from the function. Instead, we return an object literal that contains two functions. These functions have access to the variable counter, because, at creation, they were in the same scope. (Note: This last sentence may not be precisely describing the situation.) The result of this function is that object literal. My module contains two functions and a private data variable.
What’s nice is – I no longer have to worry about function collision. I can name my functions whatever I darn well please. I can also create private functions as well and hide them away from the implementation. There may be utility functions that make sense for my module but don’t make sense anywhere else. I can stuff them in there and hide them away!
So, as I said, I wanted to take out the database aspects of my code. I created a new file, diary.js, and created this module.
You can see that all of the database functions are now gone. I now access them via diaryModule.whatever. I believe I cut out about 60 or so lines of code, around a third, but what is left is more focused. (I could also take out the functions used to support my single page architecture.)
You can run this version here: http://www.raymondcamden.com/demos/2013/mar/22/v2
So, questions? Opinions? Rants?