Being boring is a good thing in software design.
There is no benefit to being impressive with a design, or to demonstrate one’s
knowledge in code. Doing that is likely to cause problems and reduce the quality
of the software.
One aspect of the programming profession is that there is both an urge and
plenty of opportunity to try to show off. We are continually learning and
improving, as we should be, and this can lead us to actively seek out
opportunities to use the interesting knowledge we have acquired, instead of
putting it to use when a concrete need for it arises.
Alex Papadimoulis
writes about this
convincingly:
““Tedious” and “boring” are two words that don’t sit well with developers.
We’re an analytical bunch and oftentimes come with a computer science degree.
And we’re much more capable than tying a front-end and a back-end together
using line after line of code. Perhaps we could even use our skills and
capabilities to make our job easier.
And therein lies the rub. As Michael A. Jackson said in his 1975 Principles of
Program Design, “Programmers… often take refuge in an understandable, but
disastrous, inclination towards complexity and ingenuity in their work.
Forbidden to design anything larger than a program, they respond by making
that program intricate enough to challenge their professional skill.”
This thirty-five year-old observation is confirmed day-in and day-out here on
TDWTF. Some of the most egregious code and stories written here stem from the
developer’s desire for cleverness. Carrying out these desires is neither
malicious nor devious, but merely instinctual.”
Here are a few thoughts on the topic in no particular order.
Means and ends
This issue frequently occurs when means are confused with ends. A common example
is the use of design patterns in OOP programming. It’s not unusual to see design
patterns become the goal in an area of code, instead of being used as a
necessary approach to actual problems.
Here’s a take on this
from Matthew P Jones:
“What patterns don’t help with is the initial design of a system. In this
phase, the only thing you should be worried about is how to faithfully and
correctly implement the business rules and procedures. Following that, you can
create a “correct” architecture, for whatever correct means to you, your
business, your clients, and your code standards.”
To be clear, I am not saying that design patterns are inherently bad or never
useful. The point here is that based on my experience so far, they are more
commonly implemented as an end unto themselves, and that is detrimental to the
production of good software
I much prefer to work on code that focuses on keeping things simple, modular and
direct than code that tries to shoe-horn in a lot of patterns. Small classes,
short methods and limited indentation will probably do more good than going
straight for a
SimpleBeanFactoryAwareAspectInstanceFactory.
A quote
from Jeff Atwood:
“Design patterns are a form of complexity. As with all complexity, I’d rather
see developers focus on simpler solutions before going straight to a complex
recipe of design patterns.”
It also bothers me when established design patterns seem to be the only ordained
way to organise code. Again, that view leads to over-complication. Quite often,
there is a small, relatively simple way to address a situation that uses one or
two more classes or interfaces. It doesn’t matter if there’s a name for this
arrangement or not. It’s about having specific solutions to specific problems,
and not creating abstraction for the sake of it.
It’s easy to overlook how far the OO in OOP can take you without thinking
explicitly about official design patterns. Use objects for things, encapsulate
and keep it simple.
Two more quotes from Jeff Atwood, one about
keeping it simple:
“Don’t use fancy OOP features just because you can. Use fancy OOP features
because they have specific, demonstrable benefit to the problem you’re trying
to solve. You laugh, but like Rico, I see this all the time. Most programmers
never met an object they didn’t like. I think it should be the other way
around: these techniques are guilty until proven innocent in the court of
KISS.”
… and another
about design patterns:
“Do you really want a junior developer using patterns everywhere? It’s about as
safe as encouraging them to “experiment” with a gas-powered chainsaw. The best
way to learn to write simple code is to write simple code! Patterns, like all
forms of compexity, should be avoided until they are absolutely necessary.
That’s the first thing beginners need to learn. Not the last thing.”
There’s even a whole site dedicated to
“Boring Technology”.
There’s
an interesting study about how using longer words does not make you appear
more intelligent; in fact, it makes people see you as less intelligent. That may
have some relevance in the world of complex software design.
Predicting the future
Attempts to predict the future are another source of needlessly interesting
software design. Trying to do this is a well-known bad practice, and there’s an
acronym to counter it: YAGNI. The
choice quote on that is probably:
“…unless your universe is very different from mine, you can’t ‘save’ time by
doing the work now, unless it will take more time to do it later than it will
to do now.”
That doesn’t quite touch upon how this idea tends to introduce pointless
complexity. In trying to predict how things will change in the future, it’s
common to design with extra abstraction in the areas we believe may change. It’s
as if we’re thinking “if I can just abstract this enough, then any change will
be easy.”
You can’t predict the future. Trying to guess how requirements will change and
pre-implement solutions now almost never improves things. It is nearly always
better to implement changes once there is a specific need to do so. At that
point, you’ve got the concrete information available to make good decisions.
Unambiguous reality leads to better solutions than under-informed guesswork.
Selection by hype
This post was first inspired by
one that Dan McKinley wrote,
so it wouldn’t be complete without a quote from him there:
“If you choose to write your website in NodeJS, you just spent one of your
innovation tokens. If you choose to use MongoDB, you just spent one of your
innovation tokens. If you choose to use service discovery tech that’s existed
for a year or less, you just spent one of your innovation tokens. If you
choose to write your own database, oh god, you’re in trouble.”
It is far from unusual to choose technology because it is new, cool and being
written about by random people on blogs. Everyone worries about being left
behind, rather than jumping on a ship that might not be headed anywhere
particularly good.
As far as I can tell, selecting by hype is rarely a disastrous decision
(although it might be), but tends to introduce a whole set of problems and extra
work that would have been avoided with a boring choice.
Also, this.
Hiring
There’s not a shortage of people writing about how hiring practices are broken
in the software industry, so I won’t go into a lot of detail about it here other
than to point out that certain hiring practices can contribute to this problem.
Candidates applying for software development positions are often encouraged to
be impressive during the hiring process. This makes sense, as an employer wants
to see the candidate’s skills in action. However, the result can be a focus on
spurious design patterns, over-complicaton and hype-selected technologies. This
is certainly not universal, but neither is it uncommon.
This may be hard to avoid, but just as I am more impressed by someone who can
express themselves clearly and directly without using rare words or complex
expressions, I would also be more impressed by someone who can solve software
problems simply, directly and with a minimum of fluff.
View post:
Boring considered beneficial
|