The Software Artisan
We all chase the thrill of a neat solution. It drives us to seek clever approaches, but the clever code that feels satisfying in the moment isn’t always what we appreciate later.
Years ago, a colleague declared they were neither a Developer nor an Engineer—they were a Software Artisan. I scoffed; “There’s no space for artisanship in software. Users don’t see your code. They just need something that works and can be maintained.” After all, artisans create beautiful things that users directly experience and appreciate. Code? It’s invisible to the end user. They just want functionality; they don’t care about the elegance of the forge that created it.
“Software Artisan” came to represent everything I thought was wrong with our industry: developers (or engineers!) obsessing over clever, convoluted solutions that looked impressive but were actually harder to understand than simpler approaches. They prioritized their creative satisfaction over user needs and maintainability; no better than a rushed hacky job at the other extreme of the scale.
Good thing I’m such a pragmatic, efficient soul, that I would never fall into such a trap, eh?
…
Turns out I might not have considered myself an Artisan, but I certainly had a tendency to act like one.
Control your Inner Artisan
You know that feeling where you’re working on some code, and you find yourself searching for a really nice way to solve the problem in front of you? You’ve got something that works: yes, there’s a comment you’d prefer not to need, and there’s a switch statement over there that feels a bit clunky and you’d have to modify the code to add a new logic branch which… well it would be a simple change, but if I just refactored this bit here into the Strategy Pattern and then moved this bit over here and then abstracted this into an interfac- STOP.
You’re over thinking it. You’re letting the Software Artisan take over. Will this massive refactor really help anyone? Or are you just going to spend days reworking something that might look better to you, but is ultimately no more maintainable or legible to anyone else than the thing you started with?
I would argue that it’s generally true and accepted that we should seek code (and process) that is (in this order):
- Functional (it’s got to do what it’s meant to do)
- Easy to understand (so that it’s clear where and when changes are needed)
- Easy to update (so that when change is needed, it’s as simple as possible)
Our industry speaks incessantly on this topic - Clean Code, Pragmatic Programming, Simple Design - I’m not going to cover the same ground again, but there are a couple of other things to consider the next time you find yourself considering a Clever solution:
1. Every refactor should be driven by a hypothesis
I will never accept “This needs refactoring” from my team, nor will I accept “this process is wrong/broken” from a team lead. We all have code & processes we don’t like, but for it to be worth updating, there has to be a benefit in doing so.
What changes as a result of us refactoring this? What benefit should we get from it? It’s preferable if we can measure it, but as a baseline I want you to be able to describe to me the positive impact of making the change.
There will be times when you Just Don’t Like a piece of code… but that doesn’t mean that the world will be better for changing it. Sometimes, you will Just Not Like a whole application, and have good reason to Not Like it, but how often do you have to use it? And what lifetime does that code have? If you only need to make a change once a year, and it takes you a week to make the change, and your refactor will save you half the time but take two weeks to do… that’s 4 years before you break even on the cost of the change, let alone see a benefit. If the whole application will end up ditched before then, then you’ll never recover the development cost.
Some problems just aren’t worth fixing.
2. Open for Extension, Open for Modification
The Open/Closed Principle had its day, but realistically these days we have Unit Tests (you have Unit Tests, right?) that will tell you if you’ve borked the original functionality. We don’t need to be so paranoid about modification to existing functionality. That means we don’t need to be quite so clever about abstractions, and trying to predict where the code will be extended.
Just do the simplest thing that will solve the problem right now, then think a little about how it might expand. Think that you might end up needing a strategy pattern here in future? Then make sure you’ve laid our your methods and functions in a way that makes it easy to create an interface from them, but don’t create the interface now. If you’re wrong, you’ve just made maintenance harder for everyone for no reason. Think you might be using a different data source in future? Same thing - don’t assume the future, but you can lay out the code in a way that makes it easy to turn simple code into interfaces later.
Appreciating your Inner Artisan
All this being said, there is space for a little Artisanship in everything we do. While most people who interact with your code will do so through the output, not the code itself, there is a group who will: other people working on this code. And while few will appreciate that you’ve written a script that uses the unique properties of prime numbers to generate an error code that can be represent compound errors with a single code (sorry, former colleagues), they will appreciate a clean, clear structure with pleasingly consistent application of syntax and structure. They’ll really appreciate code where the author has considered where people might be updating it in future.
Elegance doesn’t have to be clever; if you can find joy in the elegance of Simplicity, it will help you find satisfaction in your work that also benefits the people you work with, including Future You.
Ultimately, part of making Software Engineering attractive is making the code enjoyable to work with. There’s no harm in allowing a little artistic freedom - particularly as manager of a team - if it means that doing so engages your team of clever people who have an urge to do clever things. There is still a benefit to the urge to make everything look a little more elegant, a little more like something you’d be proud to show to another Software Engineer.
Just don’t let the Artisan have control all the time, and use your Cleverness not to impress the next person to touch your code, but to make them appreciate how much easier you made their job.