Reduce Friction Against Best Practices

When it’s crunch time, the temptation to take shortcuts can be too much to resist. Of course, crunch time is exactly when it’s most important to maintain best practices because that’s when we’re most likely to make mistakes. We can mitigate the problem by making it easier to do the right thing.

Take the simple matter of making your modules smaller. We all know that we ought to make small, simple modules, but how many of us have jammed more code into an existing module rather than incurring all the overhead of adding a new one? The overhead may include

  • adding the module to the project;
  • adding the module to a bundling configuration;
  • informing our dependency-injection framework about the new module;
  • creating a unit-testing module;
  • adding the unit-testing module to the project;
  • adding the unit-testing module to a Jasmine test.html page;
  • and maybe more.

Every one of these steps adds a little friction. If you automate away the friction, you make it more likely that developers will do the right thing.

At my workplace, we use AngularJS’s dependency-injection framework. It lets us inject pieces of code by name into other pieces of code, providing lots of unit-testable, loosely coupled goodness. However, we must tell the AngularJS framework which pieces of code correspond to which names with code like the following.

myAngularApp.service('ServiceA', MyCompany.MyApp.services.ServiceA);
myAngularApp.service('ServiceB', MyCompany.MyApp.services.ServiceB);
myAngularApp.controller('controllerA', MyCompany.MyApp.controllers.ControllerA);
// etc.

Whenever we added a new service, we had to add one more line of that. This was unnecessary friction so we automated it with a function that inspects the contents of the AnjularJS-related namespaces MyCompany.MyApp.services, MyCompany.MyApp.controllers, etc..

// app - An AngularJS application
// namespace - For example, MyCompany.MyApp.services
// angularFunc - For example, "service" or "controller"
function installAngularCode(app, namespace, angularFunc) {
  Object.keys(namespace).forEach(function (k) {
    app[angularFunc](k, namespace[k]);
  });
}

We could then do this:

installAngularCode(myAngularApp, MyCompany.MyApp.services, 'service');
installAngularCode(myAngularApp, MyCompany.MyApp.controllers, 'controller');
// etc.

Once that was set up, we never had to think about it again. It became that much easier for developers to create new, small modules rather than adding to existing ones, and more likely that they would do so.

I hope this example of reducing friction inspires you to think of others!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.