Navigation

Recruiter, please take notice!

I am not currently looking to entertain any new employment at this time. I appreciate that you think that you know the perfect position for me, but you truly don't. I would really enjoy not having to ask you to never contact me again about some 3, 4, 6, 12, 18, or more month non-JavaScript developer position anywhere in the world.

I will contact the companies that I am interested in, on my own. I am plenty capable of speaking with my future employers on my own and deciding what is the correct decision for my situation.

Commander JavaScript

9 Oct 2013

A simple introduction to the Command Pattern and some reasons why it might be a great pattern to use in JavaScript.

Preface

I have been wanting to gain some more Computer Science knowledge so I started reading more about Design Patterns. I have known about them for a long time and generally speaking my primary understanding ended at the Singleton pattern. I knew that there were other patterns defined but had no use for them since I didn't know them or how to use them.

Recently I have been building libraries of code more and have found that I like the Command Pattern a lot. Especially in JavaScript where some other language features are missing - or available depending on your point of view - which create problems for securing functionality from tampering.

Use Case

You are a developer wanting to create a new library for a particular purpose. You know that you are not going to necessarily think of everything, needed for other developers to use up front, so you want to also provide a way for them to add in features as they need to. You want to do this but don't want to allow them to harm the functionality of what you provide; at least not without them knowing that they are explicitly changing some core functionality.

Let's use the old chestnut, the shopping cart. Some required features are:

Add items to the cart

Return a list of items in the cart

Retrieve the total

Remove an item from the cart by index

I think that is enough to get started; not a fully feature complete shopping cart but enough to get some points across.

The Truly Naive Approach

The simplest way to implement this cart - in pure JavaScript - is with no encapsulation or security around it. This is something that will work perfectly if you are sure that no one will ever open a console on your shopping site and meddle with the code.

Here, the requirements have been met with the functions defined. However, I hope that no one would feel comfortable putting this code into a production environment when these are globally accessible; that is if the organization likes to be accurate when it comes to their sales.

Clean Up The Global Scope

There are a whole lot of problems in the code above and the first step towards mitigation would probably be to reduce the impact on global scope; everything is itself in the global scope. One of the early lessons in JavaScript is to not do exactly what has been done above; the suggestion is to create a namespace and include everything in one - or as few - as possible to not clutter the global scope. Let's do that now.

This is a lot better than the first attempt. The bigger problem still remains however; everything is still globally accessible. Keeping everything globally accessible like this does not prevent any code from changing the items array directly. There are other problems but lets address them later.

Using Closure For Hiding

To hide access to resources in other languages we would use access modifiers like: private, static, protected, et.al. JavaScript does not provide anything like these so we have to get creative. JavaScript does provide Closure scope and that is what we can use to great benefit.

Now, the items array is hidden away from the global scope so that is good; no code can directly change it. That isn't entirely true because in the getItems method a reference to items is returned and therefore makes it accessible; this is fixable by returning a copy of the array instead of the array itself.

Use The Command Pattern

But another issue is the cart object returned from the Closure. All of its methods are accessible; which you might think is a good thing. Callable is a good thing, changeable is not. As it stands, this code allows all of the provided methods to be overwritten in any way someone would like. It would be nice to allow the methods to be called but not changed or overwritten; until ES6 is available the Command Pattern is a good alternative.

Using this pattern everything is hidden away. The only way to call a method is to call the function cart and pass in the method you would like to invoke, along with any arguments you would like to pass into the method.