So, lately I've been obsessed with writing beautiful, modular, well-written code. To date, I feel that I've been writing code in a reactive manner - throwing things together like spaghetti, crossing my fingers and hoping it all works. For the most part they do, barely. I've been comparing my progress with learning to write code with learning to write; or at least what I remember it was like to learn to write. Now that I fell as though I can get some sentences and even paragraphs out onto the page, I'd like to be able to construct these thoughts more elegantly.
Lucky for me, a design pattern already exists for writing beautiful, modular code -- the JavaScript Module Pattern. It's also one of the more common design patterns made popular by Douglas Crockford.
var MYAPP = MYAPP || {}; // arithmetic is the namespace MYAPP.arithmetic = (function(){ 'use strict'; // this is a private property var _result = 'The result is: '; // this is a private function var _showResult = function(answer){ console.log(answer); } return { addMethod: function(num1, num2){ // console.log('this is a public method'); var sum = num1 + num2; _showResult(_result + sum); }, subtractMethod: function(num1, num2){ // console.log('this is a public method'); var subtract = num1 - num2; _showResult(_result + subtract); } }; })(); // multiplication is the namespace MYAPP.multiplication = (function(){ 'use strict'; // this is a private property var _result = 'The result is: '; // this is a private function var _showResult = function(answer){ console.log(answer); } return { multiplyMethod: function(num1, num2){ var times = num1 * num2; _showResult(_result + times); } }; })(); MYAPP.arithmetic.addMethod(4, 8); MYAPP.arithmetic.subtractMethod(24, 18); MYAPP.multiplication.multiplyMethod(4, 8);
The foundation of a module is the anonymous closure that encapsulates the code, keeping all within it private from any conflicting code another developer may write. This closure is formally known as an immediately invoked function expression aka IIFE.
(function(){ // all the code here })();
The IIFE is then assigned to a variable, which is basically the Module. In this case, I have very generically called it, MYAPP. This Module will then be used to call the methods.
var MYAPP = (function(){ // all the code here })();
Since all of the methods within the Module are private, in order for them to be made public and available to the Module, we must return an Object with the methods defined within.
var MYAPP = (function(){ return { publicMethod: function() { console.log('The information is here is public.'); } } })(); // This will output the statement 'The information is here is public.' MYAPP.publicMethod();
Now, let's create a private method and call it from the public one.
var MYAPP = (function(){ var _privateProperty = 'The information in here is public'; var _privateMethod = function(){ console.log(_privateProperty); } return { publicMethod: function(){ _privateMethod(); } } }); // This will output the statement 'The information is here is public.' MYAPP.publicMethod();
The publicMethod allows access to the _privateMethod, providing control. In the example at the top, I've created two namespaces (just for show) within the MYAPP method - arithmetic and multiplication. In the arithmetic namespace, both the addMethod and subtractMethod allow access to the private _showResult method. On the last three lines, we interact with the different methods within the Module through the namespaces.