There's an interesting nugget of advice at number 8, "The first right answer is the only answer";
Inexperienced programmers are especially susceptible to assuming that the first right answer they obtain is the only answer. Developing software for embedded systems is often frustrating. It could take days to figure out how to set those registers to get the hardware to do what is wanted. At some point, Eureka! It works. Once it works the programmer removes all the debug code, and puts that code into the module for good. Never shall that code ever change again, because it took so long to debug, nobody wants to break it.As David suggests, when dealing with complex, mission critical or concurrent sections of code, that first success is often not the best solution. Weeks later, you might find that its not performing as well as it should be in production and you have to revisit the section of code again looking for a better solution. But the best time to develop a better solution was back when the job was fresh in your mind, when you developed the original solution.
Unfortunately, that first success is often not the best answer for the task at hand. It is definitely an important step, because it is much easier to improve a working system, than to get the system to work in the first place. However, improving the answer once the first answer has been achieved seems to rarely be done, especially for parts of the code that seem to work fine. Indirectly, however, a poor design that stays might have a tremendous effect, like using up too much processor time or memory, or creating an anomaly in the timing of the system if it executes at a high priority.
As a general rule of thumb, always come up with at least two designs for anything. Quite often, the best design is in fact a compromise of other designs. If a developer can only come up with a single good design, then other experts should be consulted with to obtain alternate designs.
So he suggests adapting this into a new practice:
As a general rule of thumb, always come up with at least two designs for anything.There's multiple problems with this advice:
- YAGNI, you ain't gonna need it. Develop an extra solution only if and when you need it; don't create extra work where it might not be needed.
- Premature optimization is the root of all evil. Knowing when you need to optimize a solution further is almost impossible to do at design time, before any benchmarking or code profiling have been done.
- Lastly, if your solution passed the unit test, yet fails further down the line (in production for example), then that suggests there was a problem with your unit test, and not with your solution. If required, you should add some specific concurrency and/or performance testing to your unit test. This will mean you can then optimize your code, while maintaining a TDD approach.
I notice the original article is actually from 1999, which I believe is before test driven development came into prominence. I think this particular piece of advice ("come up with two designs for anything") might have been ok for some projects back then, but would now be considered flawed and certainly not advisable.