"What if it changes?" isn't just a question. It's a powerful heuristic for software design that can be used to justify almost anything. Everyone should use it more. It's great precisely because it's rooted in pure speculation. Once you've freed yourself from the baggage of reality, there's nothing easier than inventing scenarios where your special code will be useful under the new imaginary future conditions. If you encounter any pushback against your defensive layer cake of abstraction, interfaces, or ham-fisted design patterns, don't fret – they can't actually prove that the future you predict won't happen. That's the magic of the design rationale: the only way to fight speculation is with further speculation. You're both making the same gamble.

Developers from certain languages[0] have learned to wield this design principle with more power than many others. It's how we end up with so much stuff in code bases that's just... there. Existing. Superficially it appears unused, but silently and stoically, we know it protects us from the turbulent future change which lurks ever ahead. As I navigate through 18 levels of defensive indirection, I smile happily to myself, thankful for the warm, comforting, temporal protection created by someone with the good graces and foresight to ask "what if it changes?" before each and every line of code written.

To wield it as effectively as those who came before you, the most important thing to understand is about "what if changes?" is that you don't want or need to explore the answer. The question is the answer! Once uttered, it's just collectively understood that, without whatever cathedral of abstraction that has been constructed, the effect of a "change" would be so unbelievably damaging to the codebase that we'd all be destroyed. The grim results of not building it this way cannot be discussed in polite society. We only know it'd be devastating.

If this design principle is still new to you, here's a handy guide for getting started:

  1. Shy away from numbers or concrete analysis during design. Good engineers estimate. Great engineers speculate.
  2. Start small while you get used to the design principle. Put a wrapper (or two!) around something silly, then allude to the terrible results that may befall everyone in the future if this wrapping is not completed. The lower the stakes, the better. [1]
  3. Never audit the code base or reflect on the value of these choices over time. Definitely don't make adjustments. Why are you wrapping that one thing you use in every project? Because you've always wrapped that one thing you use in every project! It might change!
  4. Never let anyone explore the answer to your "what if it changes?" question. The impact of such a change is irrelevant! For the question to retain its power, fear must live in the imagination. The change's impact must be unstated, horrible, and so fraught with Lovecraftian terrors that only your approach can defend against it.

Now go forth.

Footnotes:

  • [0] Java, in which I currently work
  • [1] If you need a good starting idea, consider pulling all of the methods out of one class and putting them into an interface of the same name. Then rename the original class impl. Do this for all classes with exactly one implementation for maximum effectiveness