Card 06/ 08

GotchaDifficulty: Intermediate2 min

Pattern Fever: Using a Pattern Because You Know It

A factory that builds one class, a strategy with one strategy, a singleton for convenience.

Pattern fever is applying a design pattern because you know it, rather than because the code in front of you has the problem it solves. It is common just after learning the catalogue, and it produces code with more classes and less clarity than the plain version. This card shows what it looks like and the question that prevents it.

The tell is a pattern whose flexibility nobody uses: a ShapeFactory whose one method always returns a Circle, a PaymentStrategy interface with one implementation and no second on the horizon, or a Config singleton that exists because a global was convenient, when two instances would do no harm.

A factory with nothing to decide, and the code it replaces

With the patternthree names for one constructor call

py
class ShapeFactory:
    def create(self, radius: float) -> Shape:
        return Circle(radius)

factory = ShapeFactory()
shape = factory.create(2.0)

A reader has to open ShapeFactory to learn that it only ever makes circles.

Without itwhat the code actually does

py
shape = Circle(2.0)

The same object, and the reader sees its class on the line that creates it.

The factory is wrong here because the problem a factory solves, code that must not know which class it gets, is not present: there is one class, and the caller would be happy to name it. Every pattern costs something, at least one class or one level of indirection, and pays only when the problem it addresses is real.

Before adding a pattern, ask which change it protects against and whether that change has happened or is expected. If the answer is "none yet", write the plain version. It is short, and when a second shape does arrive, the plain version is easy to refactor into a factory along the line the real change needs.

The opposite mistake exists too. Copying a conditional into a fifth function because "patterns are overkill" is how code ends up needing one. The pattern belongs at the second or third occurrence of the problem, not before the first and not after the tenth.