Reuse should be a side effect, not the goal

There’s a meeting that happens in many organisations during the design phase of a new system. Someone—usually in management, sometimes in architecture—raises the idea of building “reusable components.” The pitch is compelling: if we design for reuse now, we’ll save development effort later. Future projects will be cheaper. The investment pays for itself.

It’s a reasonable-sounding argument. It’s also usually wrong.

The problem with optimising for reuse

When reusability becomes a design goal rather than a design outcome, the architecture starts to organise itself around the wrong question. Instead of asking “what does this system need to do?”—a question grounded in current, concrete business requirements—you start asking “how could this be used by systems we haven’t built yet?” That second question is speculative. You’re making decisions based on assumptions about future needs that may not materialise, or may materialise differently than you imagined.

The result is a system constrained by today’s guesses about tomorrow. Components designed to be general-purpose are often worse at their actual current purpose than components designed specifically for it. The abstraction layer that was supposed to make things flexible instead makes things complex. Future changes have to work around both the current requirements and the reuse infrastructure that was added in anticipation of needs that never arrived.

Reuse as a primary goal also suppresses the kind of creative thinking that produces good design. When your constraint is “this component must be usable by other systems,” you’re not solving the problem in front of you—you’re solving a harder, more abstract problem that may not be the right one. Good architecture emerges from deep engagement with actual requirements, not from designing to a hypothesis about future ones.

When reuse actually happens

Genuine reuse—the kind that saves real effort on real future projects—tends to emerge from different conditions. It comes from building well-structured, well-tested components that solve their immediate problem clearly. It comes from refactoring: discovering after the fact that two things in different parts of a system are doing essentially the same thing, and extracting that commonality. It comes from accumulated understanding of a domain, not from upfront speculation about it.

In other words, it comes from good design. Not from designing for it.

This doesn’t mean ignoring future concerns entirely. It means being honest about what you know versus what you’re guessing. If you have strong, concrete evidence that a component will be needed by multiple systems with similar needs—not a vague sense that it might be useful—then designing with reuse in mind is reasonable. That evidence is rarer than most architects admit.

The practical question

The test is simple: are you designing this component to solve a known, current problem, or to satisfy an assumption about future flexibility? If it’s the latter, that assumption needs to be examined carefully. Assumptions made during the design phase of a project carry a long tail—they shape the system for years, and the business conditions that seemed permanent when the system was built have a way of changing.

Design for what you know. Refactor toward what you discover. The systems that survive longest aren’t the ones designed to be reused—they’re the ones designed to be changed.