If you were to go back to some of my earliest attempts at writing code, you’d likely find a handful of files with several thousand lines of code. Why break anything apart into separate files? What if I need to edit something? It’s so simple! Everything is right here in the same file! What could be easier than that? If you’re a developer, you can probably relate. Even today, much of my code is probably too verbose and too all-encompassing. I’m always learning the best ways to break down and extrapolate into the lowest possible denominator. For me, I feel like this is an eternal struggle.
It was several years ago, and hopefully I’ve learned since then, but the desire to “make it work” is always present, especially in large projects. One of the newest code design patterns I’ve picked up has helped to keep my current work tidy and dry: the Asynchronous Module Definition, or AMD, pattern. It can be a great way to organize your code and keep it as readable as possible. It makes extensive use of the message bus we’ve talked about previously and, like the message bus, works much better with stateful programming languages. With JS it’s great; with PHP, not so much. That’s not to say that you couldn’t design a PHP application this way, but all of my experience has been with AMD JS.
In this pattern, we break apart all of the functionality of our application into small modules that can be modified without interfering with each other.
It looks something like this:
Ok. So, this is a Japanese capsule hotel, but it works as a good visualization of AMD. Each part of your code exists in small, focused, self-contained blocks. Each of the blocks has just one job. If it needs information, it just sends out a message asking for that information, and another block that is listening for that request responds. None of the blocks need to be aware of each other.
Once you’ve created the module, or block, to handle a specific job, you should be able to forget about it. Like a Roomba, it just works, even when you aren’t at home, keeping your living room cat-hair free. A well-designed module doesn’t require any modifications when you add or remove new modules, so unless you’re changing something major, there shouldn’t be any ripple effects.
By definition, this separation of concerns keeps any one file from growing too large. It doesn’t, however, automatically mean that our code is well-organized or easy to follow. When you’re trying to decide how much code to put into one module, ask yourself these questions:
- Will this functionality be used in more than one part of my application?
- Can I break this module down any further?
- Can I easily draw a map or explain how my modules interact with each other? (Spaghetti modules aren’t much better than spaghetti jQuery.)
- Is this module self-contained? (Apart from asking for data or something special from the message bus.)