Blog


JavaScript UML

Published: January 27, 2013

I have to be honest, I used to really hate working with Javascript. Pretty much every code snippet I found out there was at best organized into a couple functions and was intended to be thrown into the unmanageable mess that is most javascript code bases that are out there. My dislike only grew more as I began to appreciate traditional GoF style object oriented programming. It didn't help that every Javascript design pattern book I came across apparently decided that, rather then addressing Javascript's lack of organizational tools, the books should only talk about the patterns that were exclusively available in Javascript.

My common complains included the following:

  • How do you organize self contained classes, to allow for modular design and clearly defined class roles.
  • How do you diagram your code base to bring new programmers up to speed quickly
  • How do you dynamically load your classes without needing to inject server side code all over your Javascript files

No Javascript books I found were able to answer these questions, until I came upon Learning JavaScript Design Pattern by Addy Osmani. This book began from the GoF patterns and adapted them into multiple Javascript native patterns. It was exactly what I was looking for. There are plenty of great patterns in there, but the most important one to me is the "Revealing Module Pattern". This pattern essentially creates the basic class structure, and allows for the use of pretty much every single traditional OOP tool to work with JavaScript.

Coding Standards

I'm kind of a stickler for comments... lots of comments. To keep things consistent, I carry over much of my Python and PHP standards to Javascript. Below are a few examples, to make my coding examples easier to understand.

// Local Variables
local_variables

// Private Attributes
_privateAttributes

// Public Attributes
publicAttributes

// Class Names
ClassNames

// Functions
FunctionNames

// Methods
methodNames

// Comments
/**
 * Description of method
 *
 * @params
 * @returns
 * @throws
 */

Now that, that is covered. Lets get to the code.

Revealing Module Pattern

Below is a quick example class.

/**
 * This class doesn't really do anything
 */
var NewClass = function() {
  // Attributes

  /**
   * This is the first attribute.
   *
   * @var String
   */
  var _attributeOne = "";

  /**
   * This is the second attribute
   *
   * @var Number
   */
  var _attributeTwo = 0;

  // Methods (both public and private)

  var _privateMethod = function() {
    var result = 0;

    for (var i = 0; i < 10; i ++) {
      result += i;
    }

    return result;
  }

  var _publicMethod = function() {
    return _attributeOne
  }

  // Constructor

  var _startTime = new Date().getTime();

  // Public Method Maps

  return {
    publicMethod: _publicMethod
  }
}

var new_object = NewClass();

At first, the layout of this code looks a bit odd. The double defining of public methods seems unnecessary, and the constructor is just sort of plopped down in the middle of the code. However, if you look at the end result, the NewClass function is effectively a class, and the new_object variable is an instance of that class. In the global name space, the only variable that is publicly available is the publicMethod that returns the private variable _attributeOne.

OOP JS 1

The traditional OOP properties of this code also allows for the code to be diagrammed just like in any other language. You can see this class clearly diagrammed on the right.

Next, to make this more tangible, below is a cookie handler written in this pattern.

Example Javascript Revealing Module Pattern Class

var CookieLibrary = function() {
  /**
   * Set a cookie value
   *
   * @param string name : Name of cookie
   * @param string value : Value of cookie
   * @param integer days : Days you want to set the cookie for
   */
  var _set = function(name, value, days) {
    var expires;
    if (days) {
      var date = new Date();
      date.setTime(date.getTime()+(days*24*60*60*1000));
      expires = "; expires="+date.toGMTString();
    } else {
      expires = "";
    }
    var rootdomain = document.domain.substring(
      document.domain.search(/([\w\-]+\.\w+)$/)
    );
    document.cookie = name+"="+value+expires+"; domain="+rootdomain+";path=/";
  },

  /**
    * Get the value of a cookie
    *
    * @param string name
    * @return string
    */
  var _get = function(name) {
    var name  EQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
      var c = ca[i];
      while (c.charAt(0)==' ') c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
  }
  return {
    set: _set,
    get: _get
  }
}

var cookie_library_object = CookieLibrary();
OOP JS 2

All a programmer seeing this for the first time would need to notice is that the only two public methods on this object are get and set, and they can ignore everything else. In fact, even before they get to the code, they could see a graphic like the one to the right, in the applications UML Diagrams, and know what to expect from it even before they get to the code.

Summary

There are plenty of other details to work out when it comes to organizing Javascript code.

  • How do you organize Javascript events?
  • As I stated at the beginning of this post, how do you load up classes dynamically without server side code?
  • How do you diagram Javascript events?

All of these questions will be addressed in future blog posts. However, if anyone is curious about the solutions, the Observer and Singleton patterns take care of much of the details for the answers to these questions. Thanks again for reading this post. If you have any questions feel free to post them in the comments below or contact me on my contact page.

Additional Links

Learning JavaScript Design Patterns by Addy Osmani

http://shop.oreilly.com/product/0636920025832.do