A property with a backing variable is not DRY.

Believe it or not, I’m still not done with DRY Principle (Don’t Repeat Yourself). This short post is about a non-DRY practice that is so common you probably don’t think about it.

Can you identify how the following code is not DRY?

var myModule = (function() {
  'use strict';
  var myVariable = 0;

  return {  
    setMyVariable: function(newValue) {
      myVariable = newValue;
    },
  
    getMyVariable: function() {
      return myVariable;
    }
  };
})();


How many times have you been working with code like that and wanted to know, “Where are all the places that myVariable is set?” You have quickly realized that you must search for all occurrences of myVariable within myModule and all calls to setMyVariable() throughout the code base. In real life, myModule would be much larger and such issues become more consequential.

The same goes for getting the variable.

Furthermore, if the setter is later enhanced to validate the newValue, you have no assurance that the variable is never set directly, bypassing the validation.

If the getter is enhanced to provide a default value, you again have a potential conflict.

The DRY Principle is sometimes expressed as “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.” As I said earlier, this means much more than “avoid duplicate code.” In this example, the “piece of knowledge” of how to set the variable has two potentially conflicting representations: direct access to the variable and setMyValue. Likewise for the knowledge of how to get the variable.

It is simple to make this DRY. Just put a function like this one in your toolkit:

function Variable(initialValue) {
  'use strict';
  var value = initialValue;
  
  this.set = function(newValue) {
    value = newValue;
  };
  
  this.get = function() {
    return value;
  };
}

…and now,

var myDryModule = (function() {
  'use strict';

  return {  
    myVariable: new Variable(0)
  };
})();

// ...so you can set and get the variable like this:
myDryModule.myVariable.set(123);
console.log(myDryModule.myVariable.get()); // 123

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