Over my career, I've worked with several different companies, none of
which were able to truly make a commitment to well-crafted code. A few
were very close, but the majority of companies paid it lip-service at
best (and completely ignored it at worst). That's because a commitment
to quality code does not come for free:
- You must limit your development team to those people with the experience and capability to consistently write well-crafted code.
- Because
this talent pool is smaller, losing an employee is a greater cost.
Thus, you must be willing to compensate your "craftsmen" at a level
which minimizes turnover.
- If you choose to hire junior employees who show the skill and
interest in becoming "craftsmen", you must commit the time to mentor
them, and accept the fact some of their development efforts (especially
at first) will not "make the cut" for inclusion into the codebase.
- You will not be able to take advantage of "bargain" developers. If a
body-shop (on-shore or offshore) promises craftsman-level work at
college-grad-new-hire prices, you should probably treat them the same as
you would someone selling you a 1-year-old Porsche for the blue-book
price of a 10-year-old Volkswagen.
- You must take the time to think before you code (or
design). Research - are there commonly-accepted approaches to meet your
requirements? Consider your design at an abstract level - does it
mesh well with the framework in which it will run? This means initial
development takes a little longer (compared to the "just do it the first
way that comes to mind", or the "this is the only way I know how to do
this" approach).
- You must be willing to refactor code which fulfills the system requirements, but is poorly-written.
- You must have the discipline to maintain these ideals, even
when deadlines loom near. You must be open to the possibility of
sacrificing some functionality in order to meet a deadline.
For
much of my career, I was too busy learning my craft to really think
about things at this level. However, once I had progressed to the point
where I could recognize and produce well-crafted code, it really made
me angry: why were there no companies who were willing to make that
commitment to high-quality code, in order to reap the benefits?
- Well-crafted code has its own "beauty", and gives the developer a sense of accomplishment and pride.
- Well-crafted
code is more easily understood by other developers (if they have a
comparable level of expertise). New employees can be productive sooner,
and existing employees can maintain each others' code with less
knowledge-transfer time.
- Well-crafted code generally has fewer bugs (I'm not sure
whether that is a factor of the quality of the code, or the experience
of the developer). Bugs which do occur are usually quicker to diagnose
and repair.
- Well-crafted code is easier to extend. Future enhancements to the
product can be made more quickly, and the product will be able to
"withstand" more enhancements before its overall stability / reliability
/ performance takes a hit.
It's a no-brainer - well-crafted code is the way to go! Of
course I want a sense of pride in what I create. Of course I want to
understand new code more easily, fix bugs more quickly, and create
future enhancements more easily. Of course I want to work on a
development team comprised of "craftsman-level" developers, committed to
helping junior developers improve their skills. Of course I want to
take the time to learn and understand the best ways of building code,
and not just rush ahead with the first approach that comes to mind...
... Wait a minute... Those last couple of things are from the list of "costs", not "benefits". What happened here?
That's
when I realized - I've been looking at this purely from my own
perspective - that of a developer who loves crafting code that works in
concert with its environment, understanding design patterns, and
thinking about and discussing the best ways to approach certain abstract
problems. From that perspective, the costs of well-crafted code are
very small - so small that I viewed many of them as benefits! And of
course, the benefits are very large - "a sense of accomplishment and
pride in what you do" - Abraham Maslow would agree.
If I'm going to try to understand why well-crafted code isn't a
corporate priority, I'm going to have to look at this from a corporate
perspective. I've never been much of a business-person, so that
perspective doesn't come easily to me. But I'll give it a try in my
next blog post.
PS: if you currently work for a place which is truly
committed to well-crafted code, that's terrific - I'm jealous of you.
You're in an extremely
rare situation. Keep that in mind if you consider leaving for "greener
pastures" - you're already about as green as it gets!
There's something beautiful in a well-built dovetail joint. It works
with the wood, relatively strong in all directions without any nails or
screws to risk splitting. It looks terrific, but that's ancillary -
especially since these joints are often hidden out-of-sight, in the back
corner of a drawer. The real beauty is in how cleanly it works - as if
the wood was intended to be joined that way.
By contrast, you can hold two pieces of wood at a right angle, and
just pound nail after nail through them until they basically hold
together. It takes less time than a dovetail joint and will generally
serve the intended purpose: the drawer will hold together (for awhile,
at least).
Dovetail joints can be very challenging (almost impossible) to
create if you don't know the right technique, have the right tools, and
some degree of skill and experience. They're one of the things that
sets an experienced craftsman apart, and one of many things that makes
truly well-crafted furniture harder (and more expensive) to build.
There's also something beautiful in well-crafted code. Sometimes
it's building classes which follow the expected paradigms of the
platform on which they run. Sometimes it's execution of a proven design
pattern to solve a relevant problem. (Stress "relevant" there -
overuse or misuse of design patterns makes for ugly code, masquerading
as elegance.) It often follows the tenet, "Things should be made as
simple as possible, but no simpler" (generally attributed to Albert
Einstein).
I've been working primarily with ASP.NET for the last few years, so I'll use it as an (admittedly over-simplified) example. Most ASP.NET
development centers around a Page. Each time a Page is requested, the
framework follows a consistent series of steps to execute/construct the
page: this is the "page lifecycle". The framework incorporates a "view
state" to track user-entered data, supports re-usable components called
"controls", and supports event-based communication between the page and
its controls. Understanding these elements and how they work together
are vital "tools and techniques" for building a well-crafted ASP.NET
system. If you understand them, you'll likely write code which integrates
well with them, and you'll feel how the whole just seems to be "meant to
work that way" - like a dovetail joint in wood.
By contrast, it is possible (I've seen it many, many times) for developers to build a fully-functioning ASP.NET
system with only the barest understanding of those elements, and no
concept at all of how they interact. It's ugly and difficult to
maintain, and usually results in a lot of "whack-a-mole" fixing of bugs
(and causing more bugs in the
process). It's the software equivalent of "just pounding nail after
nail into it". But if you keep pounding at it, it will eventually work -
like the nailed-together drawer - at least for awhile.
A
furniture craftsman is perfectly capable of haphazardly nailing a drawer
together - but he (or she) won't. He takes pride in his work, and
doing a "good enough" job simply isn't fulfilling. Perhaps more
importantly, he knows just how beautiful and fulfilling a well-crafted
piece CAN be, and that knowledge makes doing "good-enough" work all the
more painful.
In my younger, less experienced days, it gave me great pleasure just
to get a piece of software working. Often, my code was of the
nail-after-nail variety - but that's to be expected. I didn't have the
skill, tools, or technique to write "dovetail joint" code. Heck, at
that time I probably didn't have the experience to fully appreciate the
difference between the two!
However today, at the risk of sounding pretentious, I am a software
craftsman. I know how good software CAN be, when it is built with an
understanding of its platform, and of common best-practices for using
it. Simply "getting the software working" no longer holds any
excitement for me; designing and writing well-crafted code is the
fulfilling aspect of my job.
So that's great, right? Experienced craftsmen are MVPs of their
professions, right? When it comes to software development, I'm not
convinced that's true. I need to mull that over a bit - it will
probably be my next post.