Software-developers nowadays are becoming latter-day Picassos: painting abstraction upon abstraction, layers upon layer, into their applications in a holistic crusade to make their work more elegant than the code next door.
If this process were to be thought of as an artistic movement – like Picasso and Braque’s cubism – its manifesto would include such rallying cries as: “I demand the freedom to change my datasource when I need to!” and “I want to unify my interfaces of data and functionality into one common format!”
These sentiments, however catchy they may be, are strong; they sound like robust and positive goals. But if we actually examine their validity, they’re really not warranted; and when implemented and put to the test in the real world, they either provide subpar performance, or fail outright.
To me it seems a false economy; how often are you really going to swap tens of thousands of pounds invested in Oracle, for example, to Microsoft SQL or MongoDB?
When such instances arise a small interface won’t help you much, since more-often-than-not it’ll have been modelled or designed to a very specific “common” look. Perhaps someone thought it would work for their problem space, but they’re unlikely to have taken into consideration a particular unknown datasource or framework that you might one day decide (or find yourself being forced) to use. Sometimes these things help, and they have their place; but the majority of the time they’re left to the wrong person to design or implement.
People seem to forget that the closer to the metal the better; the big betting companies and hedge funds understand this, and you’ll often see them looking for experienced developers with a priority on very specific knowledge of particular languages and problem spaces. And you don’t see them asking for Hibernate or Entity Framework these days…
In my practice I meet clients that are already in difficult positions where they are looking to me for help. It may be that their applications aren’t performing as well as they should, or that they have some catastrophe that needs looking at urgently. A lot of the time what I see is self-harm, where in blind fits of stupor-creativity they have built or inherited millions of millions of lines of code that isn’t even supported – or the only company or developer who knows anything about is no longer around.
It wouldn’t be so bad if it was just a LINQ-to-SQL or Hibernate framework: those things I can deal with. They are well-documented and proven frameworks that are as performant as the real thing, and if there are any problems with them it tends to be to do with how they’ve been used or configured. However, it’s the self-built frameworks with dependency-injections* galore – and as many undocumented layers as a ten-foot-high Victoria sponge – that make life difficult. There has been, unfortunately, an epidemic in recent years. Indeed, it’s still going strong and it’s in danger of turning into a pandemic.
The main problem with developers is that the promises and ideals that they’ve been brought up with in recent years force them to think what they are doing is inherently good. They are like blindfolded artists, merrily painting away in a received style to conform with an established movement – never once looking at the impact that another interface or repository layer might have on their application, to return from the metaphor. Even now, writing this article, I’m having to push aside the years of conditioning that we all have put into our heads by mentors and industry leaders. This stuff is fed to us laced with drugs to induce us into obedience and make us fight blindly, joining the crusade to convert others.
There are some specific groups that are worse than others, and mostly it comes down from above; their mentors and industry leaders pass down knowledge for their own benefit, to make money out of said group. But this practice will always fail; some abstraction is good, but not all the time.
We have a few shining beacons out there crusading for the simplistic approach, or even just asking for people to really consider their approach. The one and only thing I say to my clients in moments like that is what Uncle Ben from Spider-Man said to Peter Parker: “With great power comes great responsibility”. It couldn’t be put better than that.
With that in mind, you need a great pool of people involved during the design and architecture of a system. Sometimes it’s enough to do this only when creating the first few projects in the solution, and deciding what to use; but it’s critical you don’t spend countless hours working away on a painting which in the end could only really pass for art in the Tate Modern.
Below is a list of things I ask myself whenever I introduce something into a project, or when I design or architect a new application:
1. What performance hit will I take following this root, and can I run tests to see this?
2. What will be the barrier of entry or learning curve for newcomers to my application, and can I quantify that in minutes, hours, days or weeks?
3. What will be the time from request to delivery for the simplest piece of work (displaying, modifying and saving it)?
4. How hard will it be to debug the code?
5. How many data transformations are happening between the data store and the end user?
And if the answer to number five is more than two, I’d strongly suggest you think twice about it.
*Dependency injection can be really good, actually – but there are times when you should use it and times when you should just take the bus.
Author: Daniel Portella