Fighting my JavaScript demons with domain driven JavaScript

For quite some time now, I have been a bit uncomfortable with javascript. It is language which most developers think they they know, but in reality they don’t. It is a very forgiving language in many ways (or at least appears to be, until it bites you). It has a syntax similar to C++, Java and C# and therefore looks easy to most server side developers. Therein lies the deception. Most people (including me) fall into the false belief that we know the language, so we don’t go deep and understand how it works. Though it is a pretty powerful object oriented language, the syntax for creating objects is pretty unintuitive and by default it is easier to write procedural code and get away with it. I sort of got away with that for a few years, until recently when I was forced to look deeper.

On our codebase, we started with simple validations like blocking invalid inputs and displaying error messages. Cakewalk initially. We didn’t even bother creating any objects. But as time passed the validations and DOM transformations became more and more complicated and before we knew better, we had some shocking procedural JavaScript which got worse as more features were added. So we decided that we needed to infuse some object orientation into the code.

Most of the developers in my team (including me) were inexperienced in object oriented JavaScript. Test driven JavaScript development was new to us as well. But we gave it a try. We home rolled a MVC framework of our own. It was quite rudimentary with a view object (which changes the DOM based on the model’s state) and model object (which changes state on DOM change and notifies the view to that it’s state has changed). To a ‘server side’ developer accustomed to writing imperative code, it takes a bit of time to grasp the concept and syntax of callbacks and functions as first class objects. Again I thought that I knew the semantics and syntax of JavaScript (it was a ‘little’ different afterall). We somehow managed to write a model and view and bind them. It was certainly better than procedural spaghetti javascript that we had. A step in the right direction. Moreover we ‘test drove’ the code  in Qunit and thought we were safe.

Life went on as usual for a couple of months. Whenever there was a feature which involved javascript, we had a pattern that we used, MVC. But after sometime, the code became hard to extend and bugs started to creep in whenever a change was made. The features were getting more and more complicated so was the javascript. We had so called ‘objects’. The problem was that all of them were God objects (with a lot of sphagetti conditionals in them). Worse still, they had unit tests around them (one line of code changes and a hundred tests break). We had missed a few tricks with object oriented javascript and object orientation in general. They were

1. JavaScript is not Java or C#. It has it’s own semantics and quirks.

2. Using objects doesn’t mean that your code is object oriented.

3. Having unit tests for badly written code is worse than not having any unit tests for bad code.

4. Not having domain models in JavaScript is the biggest mistake you can make (You can get away at first, but it will bite you sooner than you think).

So how did we try to fix it

1. Read up on how JavaScript works (syntactically and semantically). A few good links are

http://javascript.crockford.com/private.html

http://www.digital-web.com/articles/scope_in_javascript/

2. After step 1, remodelled all our JavaScript models according to a domain model (The God classes were split into fine grained classes that talked to each other, in other words cohesion and loose coupling).
3. We focussed on getting the model right over writing tests (this means the code was not test driven). We wrote tests around the objects after writing the code. The idea is to get into TDD mode when people become more comfortable with JavaScript and the domain modelling.

The end result was surprisingly reusable and extendible JavaScript code. One battle against bad JavaScript was won. Though I can’t claim to be an expert in JavaScript, I certainly am much better off than before. Most developers blame JavaScript for their woes, but as Jeff Atwood says, the first rule of programming is ‘It’s always your fault’.

Advertisements

2 comments

  1. I’m making the same trek and there seems to be so many mixed opinions on how to model domain objects. Also, the JS community seems to discourage object prototypes in favor of object literals. I’m trying to find an elegant solution to the following two problems:

    1) Extending domain objects with JSON from the server
    I’ve seen two common approaches to instantiating new instances of a fully qualified domain object. One is to use a constructor function that accepts a JSON object that is used to populate the object properties. The second is to use an object literal and (using underscore or jQuery) extend the domain object with the JSON payload. For example:
    _.extend({},{})
    I want to do the second, but doing so leads me to the second problem…
    2) Utilizing the uniform access principle
    I feel like the approach that introduces the least amount of boilerplate and utility functions for creating, instantiating and extending domain objects is not the most elegant in that I access and mutate object properties with the dot notation instead of getter and setter methods. However, since I don’t want to create anemic objects, my domain objects have “smart” methods that encapsulate domain specific calculations, behavior, etc. So in my code I’m switching back and forth between accessing properties on the object directly and calling methods on the object. This is definitely not uniform, but I also don’t want to add getter and setters for every property of my objects.

    Have you found any elegant solutions to these problems? Can you provide some code examples to go along with this post, even if they are contrived but demonstrate the concerns you’ve already mentioned as well as my own?

    • @robes, I am not sure if it will answer your question, but you can take a look at post written by me some time ago. http://uttamkini.com/2013/05/25/dilemma-what-is-the-best-way-to-create-an-object-in-javascript/.
      Since JS is a very flexible language, there are a lot of ways to do something. I would follow one convention in a codebase.
      As far as properties vs getters and setters are concerned, Getters and setters are a very Java specific idiom. I also try and make objects immutable (so setters are out of the question). To access an object attribute, I use properties. All my methods are ‘smart’, i.e. used only for domain specific behaviour.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s