Sometimes I think that my next conference talk ought to be nothing more than a live read-through of Tef’s blog post, “Repeat yourself, do more than one thing, and rewrite everything”. This is a bad idea because Tef should do that, in some post-pandemic future when international travel is safe again and I can attend and buy him a drink. So I’m going to let Tef’s blog post push me off into my own direction instead, and attempt to add something useful to his wisdom bombs.
Tef’s main point—worked through via examples of common advice given to programmers that is sometimes bad advice—is that all advice has a context.
When you hear a piece of advice, you need to understand the structure and environment in place that made it true, because they can just as often make it false. Things like “Don’t Repeat Yourself” are about making a tradeoff, usually one that’s good in the small or for beginners to copy at first, but hazardous to invoke without question on larger systems. – Tef
“Don’t repeat yourself” is the advice I rail against in a recent post in this series because I saw how application of the advice damaged a particular code base. Any two code paths that looked at all similar were collapsed into single methods with long parameter lists, with flags and null checks to determine mid-flow which one of the five different entry points was in use this time. This made the code difficult to understand, debug, and change, because any change had to be verified as appropriate to make for many different entry points. Every bug we worked on required careful documentation of the many ways a specific code path could be invoked and careful mental simulation of execution for each.
Was the maintenance cost worth whatever was saved by not duplicating some smaller sections of code? No. But probably it didn’t start out that way: it started out with somebody adding an entry point and not copying code, because, well, don’t repeat yourself. And then do that a few more times, each time adding a parameter while scrupulously not repeating code, until the programmers who understood each path through were all gone.
I grind an axe here, of course. My point is that following the DRY advice dogmatically was a bad idea. It’s the dogmatism that gets you.
Dogmatism says: Don’t repeat yourself means don’t repeat any code, ever.
Dogmatism says: This particular one project management methodology is the one true methodology! Every team at this company will do agile/scrums and always-pair-program/never-pair-program while fibonacci-pointing/playing-planning-poker.
Dogmatism says: Object orientation is the only way people should structure code and therefore this programming language only has classes.
Dogmatism says: All software must follow one of the named design patterns in the Gang of Four book/some other book and if you can’t name the pattern you’re doing something wrong.
Put that way it sounds silly, right? So we do we keep doing it?
Because we don’t like the reality that we must always do the work to find the right solution to the specific problem in front of us. It’s much easier to fall back on a set of rules that we don’t have to think about or make hard decisions about. But this compromises our solutions.
There’s a blog post in me about how making tradeoffs well requires understanding clearly the values you’re using to select among possibilities. Every value is a razor you can use to make decisions. Dogmatism is a value! It makes decisions for you.
I suspect dogmatism is a value we often hold without self-reflection. That is, we can hold it as a value without being aware that it’s a value and that it is influencing our decision-making. I think it makes bad decisions. Dogmatism doesn’t let you weigh tradeoffs. And friend, it’s tradeoffs all the way down.