Notice that this code is a little more abstract than the original. This increase in abstraction makes it easier to change (as long as the change is the one you anticipated!) but slightly harder to understand.

Code is read many more times than it is written. Abstractions add changeability but increase cognitive load. The ones that are actually needed save money, those that aren’t increase costs every time anyone looks at the code.

Anticipatory complexity rarely pays off. Unless your Magic 8-Ball is far better than mine you should avoid the guessing business. Guessing right half of the time means guessing wrong the other half, and the code for wrong guesses confuses everyone who follows. The barrier to introducing a speculative abstraction is very high.

This is where the Open/Closed Principle (OCP) comes in handy. OCP is one of the core object-oriented design principles. It provides both the ‘O’ in ‘SOLID’ and guidance about when to create an abstraction.

Open/Closed is short for the phrase ‘Open for extension but closed for modification’, and this phrase, in turn, means that you should arrange things so that you can add new behavior to an application without changing its existing code.

If you find this idea incomprehensible, you’re not alone; this sounds quite impossible. However, suspend disbelief for a moment and start by imagining a world in which your applications are open/closed, where you can add new behavior without changing the code you have.

In this open/closed world two very powerful things are true:

It’s difficult to accidentally break existing code, and

the tests you have always run green.

This is programming nirvana. Open/Closed is clearly good; the problem isn’t that it’s wrong, it’s that it’s not obvious how to achieve it. We want our code to be open/closed to the next requirement but we cannot know what that requirement will be.

Are we doomed to guess? No.

Open/Closed requires that you write code that is open to the next change but it says nothing about when to do so. It doesn’t require that you guess the future, instead it tells you to write the simplest conceivable code today and then to remove your hands from the keyboard and wait. Future change requests will tell you exactly how you should have arranged the code you have.

When new requests arrive, you’ll rearrange existing code so that you can extend it with new behavior. It’s a two step process, first you refactor existing code to a more felicitous arrangement and then you write new code to implement the change. Kent Beck says it best (but I’ll paraphrase anyway): “Make the change easy … then make the easy change.”

In the absence of an explicit requirement to the contrary, Example 1 is a pleasingly simple way to arrange this code. Once you’re asked to sometimes start sentences with “This is” and other times with “This definitely is”, you’re forced to make a change.

Example 2 is not open/closed to this change. Line 15 interleaves the new code with the old, adding “This definitely is” into the existing mix, which stands a chance of breaking existing code and tests.

Example 3 / 4, in contrast, is open/closed. All of the code is needed by the existing requirement (no new behavior has been added) and rearranging this code to be open/closed to the new requirement was accomplished without changing the existing test. It can now be extended to meet the new requirement by simply passing in a new string. It’s open for extension and closed to modification.

The morals of this story are:

First, you don’t need to guess the future—sit back and wait; it will eventually arrive. Change requests are inevitably for something you did not anticipate.

Guesses serve only to muddy the cognition waters during the course of their insufficient lives.

Next, when a new request does arrive, make the change in two steps. Refactor existing code to be open to the new requirement and then “make the easy change”.

Finally, write simple code. It will likely be no more ‘right’ than your guesses but certainly will be easier to change when you figure out what you should have done.

This brings us full circle and solves your quandary in Vegas. Requirements are fleeting. Even code that is absolutely necessary today is likely to change in the future, and the odds of your guesses surviving the test of time are even longer.

The smart money bets on wrong.