Asynchronous Module Definition, or AMD, is a way of defining JavaScript classes in such a way that they can be loaded when needed, rather than loading all the classes for your system right away.  One of the principle advantages of this pattern is the increased performance of the system that inherently comes from loading fewer resources.  By leveraging the AMD pattern to create self-contained modules that can be loaded on demand one can build modules that have clearly defined dependencies and are highly cohesive.

Reducing coupling between modules makes it easier to manage functionality in a larger system.  Modules can be removed or refactored without having to go through the trouble of identifying every single usage of that code throughout your system; the coupling points between modules are clearly defined by where the module is being required.   This is doubly valuable in JavaScript where there is no clear inheritance between classes.  Throughout this post we’ll explore how the AMD pattern can help JavaScript developers write more modular code that not only helps boost performance but also makes a system significantly easier to manage and expand.

For starters, let’s take a look at the way we typically write JavaScript modules.  In particular, we’ll investigate at how we might write a reusable class. If you are familiar with the concept of prototypical inheritance and ‘IIFE’s then this will be a bit of a refresher for you.

var MyClass = function() { //instantiate the class }; MyClass.prototype = { someFunc: function(){ //some functionality occurs //This use of ModuleA is a dependency. ModuleA.someFunc(); //look, another dependency! ModuleB.someFunc(); } };

This is a pretty standard example of prototypical inheritance.  We instantiate new instances of MyClass by calling new MyClass().  This means that when invoking the methods on an instance of MyClass, the context (the ‘this’) will be that particular instance, and not every other instance that exists in memory.

But there are still some issues with this method.  For one, we’re defining everything in the global namespace, which is never a good idea.  Variables declared in the global namespace stay in memory and can potentially overwrite native functionality.  Granted, we’re only really defining the class MyClass, but it means that every bit of functionality we define for this class must be a public method on the class itself.  This could mean having a bloated class with a lot of additional methods that might not have any real use outside of being a utility method for the class itself.

We’ve also built a dependency on two other modules, ModuleA and ModuleB.  We’ll discuss that issue in a bit.

So let’s try another approach to writing this class:

var MyClass = (function(){ var MyClass = function() { //instantiate the class }; MyClass.prototype = { someFunc: function(){ //some functionality occurs ModuleA.someFunc(); ModuleB.someFunc(); } }; return MyClass; })();

This is an example of an IIFE (immediately invoked function expression, pronounced “iffy”).   This has become a fairly prevalent way of defining JavaScript classes since it has the nice benefit of keeping all of the inner workings of the class organized and private without polluting the global namespace.  Actually, having your class defined in its own closure is great because anything that you define within the scope of that closure is going to be exactly what you expect it to be.  Even if the same variable name is declared globally elsewhere, so long as you declare it properly within your closure (read: with a var in front of it) it’s safe.

In fact, we can leverage the fact that our class is defined in a closure to help keep track of our external dependencies as well.  Since we are immediately invoking our closing function, we can also pass dependencies as arguments.  Now we are clearly defining the dependencies near the top of our closure, enabling us to keep track of them within the scope of our class:

var MyClass = (function(A, B) { var MyClass = function() { … } … return MyClass; })(ModuleA, ModuleB);

This is a pretty popular technique to use when loading frameworks such as jQuery, Mootools or Prototype, which all use the ‘$’ as a variable name.  By passing in the specific framework you want to use in your closure you can clearly define what ‘$’ actually means.  This is a great way to handle migrations from one framework to the other; both frameworks can exist in the system simultaneously without fear of conflict, since the actual implementation of the framework is happening safely from within a closure.

If you’re already writing your code this way then you’ve already come a long way towards writing better JavaScript.  Even so, we can take this concept farther. While we’ve scoped out our dependent modules, (and this is a good thing), our code can still fail if those modules aren’t loaded before this one.  We’re bound to a strict load order.  Consider this: MyClass has a dependency on ModuleA and ModuleB.  ModuleA could have one or more dependencies as well, and those dependencies can have dependencies all of their own!  You can see how the complexity can grow.

This is in part what happens in a tightly coupled system.  We’ve created what can be described as a dependency web – so many classes and modules that are dependent on other classes and modules that if you were to draw a diagram showing the relationship between all your classes it would look something like a spider web.  This is hardly a problem when you have 2 or 3 JavaScript modules that are being loaded.  However, when a system starts to have more classes, this web can quickly become unmanageable.  Removing or refactoring a module can become a harrowing experience that may have unexpected ramifications on the entire system.,/p>

One way of addressing this unnecessary complexity is by using the AMD pattern to define modules.

A Note on RequireJS

While there are a few AMD frameworks in existence, I’ve had the most experience with RequireJS.  It’s widely used and very well documented.  It can also be implemented on NodeJS projects in addition to traditional JavaScript projects.  Details can be found at requirejs.org.

All the examples in this article will use RequireJS, but the concepts and patterns are consistent with other AMD frameworks.

Moving Right Along…

As I mentioned at the start of this article, the AMD pattern is a way of loading JavaScript modules when you need them.  By using strings to identify dependencies we have not only a list of dependencies defined for a module right at the top, but we also have the ability to retrieve those modules if they have not already been loaded into the system.  Let’s take a look at an example using MyClass:

define(‘myClass’, [‘moduleA’, ‘moduleB’], function(A, B){ var MyClass = function(){ … }; … return MyClass; });

and when we want to load the module:

require([‘myClass’], function(MyClass) { new MyClass(); });

Let’s take a moment to break down what’s going on here:

The “define” method takes three arguments; a string identifier, an array of required modules, and a function that will be invoked when the module is loaded.  The function is associated with the string identifier; when that string identifier is required (as are the strings listed in the array), the function is invoked, passing in the required module as an argument.  So, by listing ‘moduleA’ and ‘moduleB’ in the array of required modules, we are loading them as the arguments A and B within the scope of the function, assuming that ModuleA and ModuleB actually return something.  Since we are talking about modules as classes, let’s assume they do.

The string identifier also happens to be a relative path to the module (the base path can be defined when the AMD framework is initialized; see the documentation for whichever framework you are using!).  This means that the script file containing your module does not have to be loaded until that script is needed, which certainly has ramifications on performance, which we will discuss later.  There are two important side effects of being able to load modules in this way: one, your code must be highly cohesive; and two, you must make sure that any dependencies are loaded prior to or as you load this module.

By highly cohesive, we mean to say that the code inside this module is specific to the functionality of the module.  Any functions, anonymous or otherwise, should be necessary for the module to perform its intended task: no more, no less.  It’s already a good idea to avoid including functionality that has nothing to do with the class of which it is a part.  It’s similar to talking about advanced programming techniques in an American literature lecture (or vice versa); you’re probably doing something very clever, but chances are that’s not what your audience came for.  When you (or another developer) are requiring your module, they are calling for a specific set of functionality.  If a developer requires a module called “Carousel”, it should contain code for a carousel user interface and not a method for parsing JSON strings.  If the functionality is private, then it will never be exposed outside of the scope of your module.  If it’s publicly exposed, then chances are that most developers using your code may never know it’s there, and even if they do, they may question what that odd method has to do with the module you created.  If you’ve included code that is outside of the define statement then you’ve defeated the purpose of using an AMD pattern, since now you are loading code that cannot be explicitly referenced inside the scope of the requiring module.  Not to mention that it’s now floating in the global namespace, which, as we discussed earlier, is not a good idea.  One of the goals in writing more modular code is to keep a module as specific as possible.  If you find that you are writing code to perform some utilitarian function that is not inherently specific to the module containing it, consider elevating that code to its own module, or to a module containing utility methods that are reused throughout many scripts.  The AMD pattern helps guide us into writing code that is designed for a singular purpose.

The AMD pattern also forces us to consider how and when our code is loaded.  Consider that one of the benefits mentioned above is that the load order of files is no longer a problem; files are loaded when the module they are associated with is requested.  The define method takes as an argument an array of modules that we wish to load with the module we are defining.  We can load any or all of the modules on which the new module is dependent, so long as those modules have been defined as AMD modules.  It behooves us to indicate which modules we wish to load with our new module; not only do we have a list of dependencies at the top of our module, we are also guaranteeing that these modules will be available as soon as we load our new module.

As a side effect, we’ve also provided a coupling point for our dependent modules.  We don’t have explicit references to our dependent modules throughout our code.  Note that we can define our required modules however we like within the scope of the module that requires them.  This means that we can change which modules are used within a closure by simply changing what module is required.  Take, for example, the following code:

require(‘myclass’, [‘moduleA’], function(A){ … });

Consider a scenario where major refactoring has been done on moduleA to eliminate a lot of functionality that is no longer needed by newer webpages, but older pages still need the older version.  The refactored version of the module is defined as ‘moduleANew’.  We could search through each of the classes for references moduleA and replace each explicit reference to the module to ‘moduleANew’.   We could also just change which module is required:

require(‘myclass’, [‘moduleANew’], function(A){ … });

Now our module ‘myclass’ will use the newer, refactored code, while modules still dependent on the legacy code will not break.  Furthermore, by leveraging the AMD pattern to load our modules asynchronously, there is no need to load both moduleA and moduleANew.  The appropriate module will be loaded automatically.

Some Thoughts on Performance

We’ve highlighted how using the AMD pattern can improve the maintainability of your system.  Now we’ll discuss how this modularity can also have an effect on the performance of your system.  We’ve already discussed the potential performance gains from not loading script until it is needed.  In short, loading code when it is necessary means less code allocated to memory.  In the context of a website, this means that you will have a faster initial page load time.  The subsequent time and memory required to load modules later on isn’t reduced, but it is distributed throughout the user’s experience and more often than not will be negligible.

Performance is not just the amount of space and time it takes to load a module; it’s also the amount of time it takes to execute the code.  It is not uncommon to have a module that performs a certain action depending on a state or condition.  Let’s say we’ve created a reusable module for rendering a tabbed user interface.  In the interest of making it useful for multiple pages on the site, the module has code for different types of animations and button types.  Each time the user interacts with the tab interface the module must determine what functionality is to be used for this implementation:

If (this.options.animated) { If (this.options.animationMode === ‘vertical’) { //animate vertically } else if (this.options.animationMode === ‘horizontal’) { //animate horizontally } else { //no animation mode, do the default logic } } else { //default logic }

This example highlights how potentially complex our reusable module can get.  In order to make our module useful for a variety of scenarios we need to make sure it encompasses the needs of that implementation.  However, every time this code is executed we must evaluate a series of conditionals to determine what the desired functionality should be.  A single conditional may not seem like a huge performance hit but as our behaviors become more numerous and complex our code takes longer to execute.  We could separate the different branches in our logic into multiple versions of our tab module but then we’ve defeated the purpose of having a reusable module.

Consider an alternative; if we know what functionality we need when the module is instantiated, we can use the AMD pattern to load the appropriate parts of the module when it’s needed.  Imagine if, instead of having one method to change tabs encompassing all possible interactions, we required the script that extends our base class with the appropriate tab method.  We’re explicitly defining what functionality our module should have without needing to re-write the entire module.  Because we are leveraging an AMD pattern to load that functionality, it isn’t necessary to load all of the code that could possibly be associated with the module; we have only the code we need.

Because JavaScript doesn’t have the same notion of class inheritance that is present in other object-oriented programming languages, it falls to the developer to maintain dependencies between modules.  It can become almost unrealistic in larger systems to keep track of all of the coupling points between modules.  The AMD pattern goes a long way towards helping developers build systems that are loosely coupled to each other through clearly defined points of interaction.  These interaction points easily identify the module’s dependencies.  Moreover, it helps developers write modules that are self-contained and specific to the intended use of the module.  These principles, when applied to any system, can take the insanity out of maintaining and scaling any JavaScript system and lead to code that is more reusable, more stable and performs better.

Posted on by Andrew Larkin | Leave a comment

5 Lessons JavaScripters Can Learn From Java Unit Testing

Lately I’ve been trying to be more of a full-stack developer, which means getting out of that comfort zone that is Javascript and branching out into the wider world of object-oriented programming languages.  And no, I’m not cheating and just doing everything in NodeJS.  At work that means taking on a bit of Java.  Boldly I dust off IntelliJ and dive right in. What I’ve discovered is that there’s a lot a traditional JavaScripter can learn from a little bit of middleware development.  In particular, Java unit testing can give some insights into how to write better tests in JavaScript. I’m a total advocate when it comes to the benefit of code testing and test-driven development, to the point of working on a test framework for CSS.  It surprises me how resistant many front-end developers are when it comes to writing unit tests.  I’ve been known to give impassioned lectures over beers about the wonders of unit testing.  So, to that end, I’ve come up with five lessons JavaScripters can take with them from the world of Java unit testing.

1 – Don’t Write Five Tests When One Will Get You Covered

This is one that I struggle with a lot.  I enjoy writing unit tests.  There’s something so rewarding about seeing all your tests switch to green when they pass.  Sometimes I get a bit carried away and start writing tests for every single bit of logic in my module.  I tend to produce very large test specs. The goal of testing isn’t to write the most lines of tests, it’s to make sure your code is completely covered.  Make sure that all your branches are touched by your tests; if you have an “if” statement, make sure you have a test for both conditions.  Test for error states.  But don’t write five tests for the same branch of logic, even if they are testing different things.   Java unit tests will fail if something goes wrong.  Likewise, if you’re writing tests that explore every branch of logic in your JavaScript you will capture any errors that might occur.

2 – Test What You’re Testing

If you’ve worked with Java before, you know how sprawling a system can become.  Classes extend other classes, there are dependencies upon dependencies and generally it takes a bit to find things.  There’s a reason why Java IDEs tend to be so feature-laden; it’s almost impossible to work otherwise.  Often methods that are being used by a class are native functionality or part of another well-tested library.  It’s pretty safe to assume that if it isn’t part of the class you are writing a test for, you won’t need to test it. This is a pitfall that a developer can fall in to in writing JavaScript tests.  In a world where we rely heavily on frameworks such as jQuery it’s tempting to assert that we’re actually selecting the right div.  Guess what: jQuery works.  Trust me (they have tests!)  Focus on testing the functionality that is specific to your class or module and leave the code coverage for other classes to their own test suites.  Instead, consider lession #3…

3 – Mocking is Your Best Friend

A lot of JavaScript developers seem to get hung up on the fact that it’s hard to write effective tests if you aren’t loading a website.  It’s hard to think how effective a test will be if the module you are testing needs to reference DOM elements and you don’t have a DOM.  It’s especially frustrating when trying to test a block of code that references another module that can’t run without a third module.  Before you know it, you’re practically loading every JavaScript module and class in your application.  (aside: if you have this much interdependency in your JavaScript you may want to consider making your code a bit more loosely coupled!) This is where mocking comes into play.  When writing Java unit tests, you are going to have to mock data.  More often than not a test will require that data is mocked in order to assert that certain functionality has occurred.  Mocking data is a way of uncoupling code so that you can focus on testing the class in question.  JavaScript testing frameworks such as Jasmine even allow you to “spy” on a function call; a spy will prevent the actual function from being invoked and will instead allow you to determine what the call returns, thus allowing you to simulate calls to other modules without having to actually call it. What if it is virtually impossible to mock a function call?  Then your code is probably a candidate for a bit of refactoring.  After all, part of the process of writing tests is to make new discoveries about your code.

4 – Just Because It’s Private, Doesn’t Mean It Can’t Be Tested

Unlike JavaScript, Java has an explicit notion of public and private functions and properties.  These properties and methods can still be tested so long as the public methods that reference the private properties are tested.  The goal of writing a good unit test is to ensure that, given a certain set of data going into your method, certain data is going to come out. Javascript may not be able to define properties and methods as public and private, but it certainly has scope.  Often we resist exposing all the functions of a module or class outside of its scope in order to maintain the integrity of the code.  This is not a horrible thing, so long as we can test the code that references the private methods. With properties that aren’t explicitly exposed, consider using getter and setter methods, much in the same way Java does.  That way, properties can be set by your test suite and defensive code can be written to validate that properties aren’t being set in inappropriate ways.

5 – JavaScript Testing is Way Easier Than Java Testing

Seriously, it’s true.  We have it easy.  Writing tests in Java involves setting up the correct test framework, making sure all the appropriate libraries are imported, and compiling your code every time you want to test it.  Most JavaScript test frameworks work right out of the box with very little configuration required.  Even EnvJasmine, which allows you to automate testing on the JVM, works with very little configuration.  Just write a spec and go!  Moreover, it takes less time to validate that your tests are working since JavaScript doesn’t need to be compiled.  Less time to compile means more time to code! Lastly, because JavaScript is such a flexible language, it’s often easier to find creative ways to validate your code.  There are multiple ways to test asynchronous methods, for example.  Need to mock data?  You can either create a spy or make a fake version of the data right in your spec.  We JavaScripters can be a wily and creative lot; there’s no reason we shouldn’t leverage that to write better tests and, subsequently, write better code.
Posted in Uncategorized | 1 Comment

Pick a style and stick with it

So I spend a lot of time thinking about code quality. Not that thinking about code quality is a particularly unique or clever thing to say one does.  I mean, if you’re making bridges, I’m sure you think about bridge quality a lot. Or at least, I really hope you do, because, I mean, bridges… they need to be pretty solid. I’m not the first to compare bridge building to software engineering, and the consequences of building a shoddy bridge are far more dire than the fallout from shipping bad code.  Us software engineers still spend a lot of time thinking about how to make our code better. Or at least, I really hope you do. And if you do, you might have discovered that one software engineer’s idea of an improvement in code quality might be very very different from yours.  For example, I’ve seen JavaScript code that has been optimized for performance only to make it almost, but not quite, entirely unreadable by the next developer.  Is the code better?  Well, it may be faster, and that’s certainly a good thing.  But the next developer who touches the code is now going to have to interpret the very clever optimization.  Chances are, that developer is going to miss something important.  Mistakes will be made.  Bugs will be filed. I was speaking with a coworker the other day about how to improve code quality and the issue of readability and understandability came up.  Many issues arise out of the fact that one developer writes very clever code that another developer can’t wrap his brain around.  Too often we encounter “untestable” code for which is is very challenging to write unit tests.  It becomes very difficult to merge functionality because the way two classes were written are almost entirely different. So as I thought about our very large and old code base, the thought popped into my head: Pick a style and stick with it. Developers, JavaScript developers in particular, have a lot of freedom and flexibility when it comes to writing code.  We all add our personal flair and style to the way we program.  The trouble is, when a bunch of developers are working on the same codebase it becomes a hodgepodge of varying styles.  It’s kind of like asking Picasso to pick up and finish a painting by Van Gogh; yeah, he can get the job done, but it’s not going to have the same original intention of the artist.  And when Rembrandt comes along to tweak the painting three months from now, he’s going to have an extra challenge in figuring out what’s going on. While it partially pains me to suggest it, the solution is to standardize design patterns.    Standardize the way that classes are structured within the organization.  It’s a hard thing to do, to ask a developer to sacrifice personal style to conform to a particular way of writing code, but the gains are so very worth it, especially for larger organizations.  Make it easy for developers to understand what a block of code is doing by making it familiar and consistent.   Make it easier to write unit tests and simpler to find problems by keeping the code consistent. I may spend a lot of time thinking about code quality, but the less we as developers have to do to make our code better, the better our code will get.  It’s quality through consistency, and it’s a pretty good idea.  
Posted in Uncategorized | 1 Comment