Pluggable Code: How a Well-Designed Application Supports Mass Mutation

We can use many attributes to describe a good application: changeable, future-proof, well designed, or flexible are just a few of them. What does this mean? Is this just a challenge for the most uncommon word pair? Or is there something behind those words that we can measure?

My work gave me a good example on what quality is and how it affects changes in existing applications. The two applications where in production for more than a year and in both where mass mutations not a built-in feature. How much effort can it be to add that “simple” additional requirement?

 

What is mass mutation?

Mass mutation or batch processing covers everything where you need to do the same activity for many times: sending a reminder to all customers who have not paid their bill, change all users of an outdated subscription plan to a current one or recreate a document after fixing a bug.

Those activities would be great candidates for automation, therefore something technical and put on hold to create customer value with other stories. Unfortunately, that is not true. Those stories are not technical; they cover the core business and make a significant difference to productivity.

It is only a question of time until the business declines the idea to click thousands of time to regenerate documents. When this happens, time is an issue and there is no money left for implementing that feature. Now is the time where it matters how the application was designed and you are going to find out how flexible the design really is.

 

The well-designed application

Well-designed means for me that there are clear boundaries between components that do a specific task. Tests ensure that our expectations on a module are correct and that there are no side effects we do not know about.

Our application already does the single-case activity. For mass-mutation, we need to do it multiple times without user interaction. We already have code that works and we only need a small amount of code to do that activity – our tests ensure this. All we have to do is to create a small application that runs that code with the different parameters; our tool does what the user would to, just faster and without manual interaction.

To regenerate all PDF files we had to do this:

  1. Create a command line application
  2. Iterate over all our orders
  3. Create a new workflow
    • Add the step to remove the current file
    • Add the step to create the new file

To implement a mass-mutation feature needed less than 20 lines of code, created workflows for a few minutes and then the application processed them all within an hour – as it does with all the workflows created by the users.

If other documents need to be recreated we can make small adjustments to that tool and can reuse most of our work.

 

The monolith

The opposite of a well-designed application is for me the monolith. They have often no boundaries, no tests and many side effects.

Those applications can do the single-case activity as well, but this time no one knows how the monolith does it. It may be in this part, but it could also be there. Without tests, we simply do not know and we need nearly the whole application running to get it done. It most often depends on the environment and that means we cannot reuse the code for the single-case. We quickly end up writing browser automation and do what the user does – this time in an automated way.

Our second application is one of those monoliths and we only could use browser-automation:

  1. Create a command line application that runs the browser
  2. Find the elements to click through the application
  3. Handle all the error cases with waits and additional checks
  4. Go back and fix even more errors
  5. Go back again and fix session timeouts and network errors because it runs for so long

To implement a mass-mutation feature needed more than 100 lines of code and a lot of error handling. Running the tool took multiple days and whenever something changes, you start from scratch.

Yes, we got mass-mutation working for a single case. However, when a slightly different requirement pops-up, we can only reuse a small part and do the work all over again.

 

Parting thoughts

Well-designed is not only a word. It makes a big difference whenever you need to change the application. Mass-mutation and bulk processing are only two different activities that tend to come in late and show you how easy your application can be changed. Whenever possible, create clear boundaries and make sure that you do not need the whole application to run a small part of the functionality.

Leave a Comment

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