Tools of The Effective Developer: Make It Work – First!
I’ve come across many different types of developers during my nearly two decades in the business. In my experience there are two developer character type extremes: the ones that always seek and settle with the simplest solution, and the ones that seek the perfect solution, perfect in terms of efficiency, readability or code elegance.
Developers from the first group constantly create mess and agony among fellow developers. The second group contain developers that never produce anything of value since they care more for the code than they do for the result. The optimal balance is somewhere in between, but regardless of what type of developer you are: you should always start by making it work, meaning implement the simplest solution first.
Why spend time on an implementation that isn’t likely to be the final one, you might ask. Here’s why:
- The simple solution helps evolving the unit-testing safety net.
- The simple solution provide rapid feedback, and may prevent extensive coding of the wrong feature. It is like a prototype on the code level.
- The simple solution is often good enough, and – with a working solution ready – you are less inclined to proceed and implement a more complex solution unless you really have to. Thus avoiding premature optimization and premature design, that makes you add features that might be needed in the future.
- With the simple solution in place, most integration and programming interfacing is done. That makes it easier to implement a more complex solution.
- While implementing the simple solution, your knowledge of the system increases. This helps you make good decisions later on.
This may all sound simple enough to you. After all, the habit of Making It Work First comes naturally to many developers. Unfortunately, for me, I’m not one of those developers. I still let more or less insignificant design issues consume an unnecessary amount of time. The thing is, it is hard to find the perfect design on the first try. The perfect design may not even exist, or cost too much to be worth the effort.
That is why I struggle to attain the habit of Making It Work First.
Previous posts in the Tools of The Effective Developer series:
It’s usually a management problem – as often as not just you managing yourself. Once you write the quick version, noone’s going to allocate you time to write it properly. Eventually you’ll pay for it.
Good point, and in my own experience very true. This is a two-layered problem:
On one side, if you aren’t allowed to do proper refactoring, you – and the whole team – will get maintenance problems later on. So, as a developer, always insist on your right to refactor.
On the other hand, if your quick solution is properly refactored, but you aren’t allowed to take it a step further, like making optimizations or making it prepared for future needs, then it could be a sign that the quick solution is good enough (Think business value). It’s either that, or insufficient testing (to convince management).
I fall into the first category you mention- avoiding over-engineering at all costs. I do see how this leads me to trouble maintaining code some times, but usually the problem comes from not ever refactoring my code. At work this is because people (clients and bosses) see the app working and just move on to the next item, and with my personal work it’s just a matter of not having as much time as I’d like.
How do you explain to non-technical people that you need to bill x-amount of hours to a project after it “works”?
And I started out in the second category, but with wisdom of age moved towards the middle. I see from your website that you are a web developer. It’s funny, but in my experience web developers are overrepresented in the first category. (This is not a critique towards web developers, just an observation. And if I must choose between the two extreme categories I’d pick the first without hesitation: It’s better to get things done, than not.)
Regarding your question, here’s my advice: don’t tell the non-technical people it “works” until you’re done refactoring. (But show them before optimizing.)
Good idea – let them see some functionality, but explain that it isn’t complete yet until you get at least one run through optimizing it. Thanks!
I’d say this is part of an agile practice: make it work, and keep it working. I try to have a working version of my code that passes all smoke tests every day, or every week at the latest.
By the way, what’s with requiring JavaScript in order to post comments?
Thanks for your comment, I’d call it agile too.
I guess the WordPress plugin Brian’s Threaded Comments are to blame for the JavaScript requirement. I’m sorry about the inconvenience but it’s a really great plugin.
Don’t confuse simplicity of a solution with effort required to arrive at it. Simplest solution is usually not be the first come to mind.
Do you mean to say “least effort” in place of simplest?
Good point!
I meant “least effort”, but that’s how I define simplicity. The simplest solution, as you pointed out, is not necessarily the first that comes to mind.
Good posting. I call these tendencies under and over-engineering. I started writing a comment about this here, but it got long, so I put it in my own blog: under-engineering, over-engineering, right-engineering.
Thank you!
Your post is excellent.
There are two kinds of developers: those that try to write perfect code and those with experience.
That’s another way to put it 🙂
The two kinds of programmers are
1. Messy Programmer (under or over engineered), and
2. Neat Programmer (who also clean up others’ messes).
The second category is careful balance of all the conflicting requirements (stated and unstated). Yes, most programmers fall into the Messy category. They leave behind an unmaintainable mess.
However, it is imprecise to describe Messy Programmers with positive words like simple and perfect. Most of the time the “simple” programmer is writing code that ignores real-world use. He makes production systems that crash easily and no one can figure out why. The “perfect” programmer writes code that no one can decipher. He also makes production systems that crash often and no one can figure out why.
The person I call the Neat Programmer is neither fast nor slow; he rides the middle ground. He ensures that his code is understandable, maintainable, extendable, and testable–but not at the cost of creating whizbang frameworks when much less is required.
“but not at the cost of creating whizbang frameworks when much less is required”
Right on!