For the last two issues, I spent time reflecting on various lessons and concepts that I've learned in my two and a half decades as a software developer. This editorial officially turns this duo of articles into a trilogy. For this issue's treatise on software development, I'll explore an infrequently discussed yet ever-important topic: technology choice as it applies to application maintainability.
There is an old saying among software developers: Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.
Over the last two months, I've encountered two codebases in which I wish I could take on the role of psychopath and stalk the homes of the developers who created these monstrosities. What's my issue with these particular codebases? Two words: over engineering. Each of these projects had a rather simple set of requirements but were so over-engineered that they were practically unmaintainable.
Let's talk about each project individually.
The first project had a rather simple set of requirements:
- Read two types of comma-separated files (CSV) found in a specified directory.
- Read each row from the file.
- Transform and attach lookup data to each record processed.
- Create an Excel output file from the transformed data.
That seems like a pretty simple set of requirements, right?
The codebase for this project was a conglomeration of new trinkets and shiny bobbles, aggregated into a Rube Goldberg set of steps in order to complete what seemed a simple set of tasks. The project used reactive extensions to throw events when files were added to a folder, and for each type of file it processed, it started a new multi-threaded task. It also used an aggregation pattern to collect exceptions, and so on and so forth. My major problem was that it took a simple process and convoluted/abstracted it into an event-driven spaghetti monster. It made more sense to rewrite it than to try and make modifications to the code.
The second application was a Web portal for a mobile application. It had another simple set of requirements:
- Provide an internal API for signing up users.
- Provide an internal API for two types of lookup lists.
- Provide a Web interface for maintaining the list of users.
- Provide a Web interface for maintaining the two sets of lookups
Note that the internal designation on the API calls means that they won't be called by external users; in other words, they'll never be public.
As you can see, it was another set of simple requirements. When I see this list of requirements, ASP.NET/MVC seems like a great platform for such a simple application. ASP.NET/MVC has a great view engine, capabilities for returning data in XML, JSON, and other formats, and is, in general, a complete Web development stack. Of course, this application was backed up by a database such as SQL Server or MySQL (the client's choice).
I want to point out one more little item. This application is for a small startup with a very niche process. It is not now, nor will it ever be, an application requiring “Web scale.” For those following along at home, Web-scale means that it will grow to be on the scale of Facebook, Twitter, Instagram or many other large scale Web-based applications. Most applications are many, many orders of magnitude smaller and should be designed accordingly. This is very important to understand; I'll explain why further later on.
There are two major issues I found with this codebase. The first is that they used the ASP.NET Web API as the back-end platform. The second is that they used AngularJS as a platform for providing the portal to this application. You might be a saying to yourself: “What's wrong with these choices?” On a technical level, there's nothing wrong. ASP.NET Web API and AngularJS are fine choices for building applications. The real question is: “Are they necessary and what benefits do they provide?”
Here's where I find fault. ASP.NET MVC provides a single platform that's plenty scalable for this application and has a well-vetted and powerful view engine. There's no need for AngularJS (another language and stack to learn) when the tools are readily available in a single tool.
So why did the developers choose this particular Web stack? My guess is that there were two reasons. They heard about mobile applications and app store and had dreams (or delusions) of Web-scale. Let's stick a fork in that one. Not too many applications require Web-scale and for developers to spend the time and resources to attempt it is borderline irresponsible. You're probably NOT going to build an application requiring Web-scale in your lifetime, so don't prematurely optimize for it.
Secondly they probably wanted to learn Web API and Angular and had a client foot the bill for their learning curve. These are only guesses but I've a feeling that they might be have elements of truth to them. For the record, this project went over budget and over schedule and I believe the choices made by the developers are partially responsible for that.
Consider the long-term maintenance costs for any tool you use to develop or you'll always be looking over your shoulder for that psychopath.
In my initial statement, I said that I would cover technology choices as they apply to software maintainability. Hopefully, with the two examples provided, you can see how two rather simple projects can become costly to understand (which is a pre-requisite for maintainability) because the developers made poor technological choices. Every time you choose a particular set of tools, you need to consider the long-term maintenance costs for that tool or set of tools. Every new tool/technique increases the learning curve for the next developer (probably not you).
So my advice to you is: Keep your technology footprint as small as possible (reduce the learning curve) and choose the right tool for the job (just not the one you want to learn).