XP / Engineering Practices

Simple Design

An XP principle that advocates building the simplest solution that could possibly work, adding complexity only when proven necessary by actual requirements.

Senior Test Lead

What it is

Simple Design is one of Kent Beck’s four rules of XP design, ordered by priority:

  1. Passes all tests. The design must work. Untested or broken code is not simple; it is wrong.
  2. Reveals intent. The code should clearly communicate what it does. Names, structure, and flow should minimise the mental effort required to understand it.
  3. No duplication. Every piece of knowledge should have a single, unambiguous representation. Duplication breeds inconsistency and maintenance cost.
  4. Fewest classes and methods. Once the above three are satisfied, remove anything that does not earn its keep. Fewer moving parts means fewer things to break.

Simple Design fights speculative generality — the temptation to build abstractions for requirements that do not exist yet. It asks: what is the smallest, clearest thing that solves the problem today? Not tomorrow. Today.

Simple is not easy. Simple Design often requires more thought than a complex one. It is easier to add layers, frameworks, and indirection than to find the clean, minimal expression of a solution.

When to use it

Every design decision. Every code review. Every time you are tempted to introduce an interface, a base class, or a microservice “just in case.” Simple Design is a lens, not a phase.

During code review, ask four questions: Does this pass its tests? Is the intent obvious? Is there duplication? Can anything be removed without breaking the first three rules? If the answer to all four is yes, the design is simple enough.

Key benefits: faster delivery, lower cognitive load, easier onboarding, fewer bugs, and code that bends rather than breaks when requirements change.

Key concepts

The Four Rules

The rules are ordered by priority for a reason. A design with no duplication but failing tests is not simple. A design with fewest methods but obscure intent is not simple. Work down the list, never up.

Speculative Generality

Building a plugin architecture when you have one plugin. Abstracting a database layer when you have one database. Creating a factory when you instantiate one type. These are all speculative generality. The complexity tax is paid immediately; the benefit may never arrive.

YAGNI

“You Aren’t Gonna Need It.” A slogan, not a law. The point is not that you will never need the feature; it is that you do not need it now, and building it now costs more than building it later when you actually know what you need.

Emergent Design

Rather than designing the whole system up front, let the design emerge from working code. Start simple. When a real requirement forces complexity, refactor the simple code into a slightly more complex form. Repeat. The result is a design that matches the actual problem, not an imagined one.

Symptom Likely Cause Simple Design Response
Empty interfaces or base classes Speculative generality Delete them; reintroduce only when multiple implementations exist
Deep inheritance hierarchies Premature abstraction Prefer composition; flatten to what the current features require
Unused configuration options Anticipating future needs Remove; hard-code the one value you actually use

Common pitfalls

  • Confusing simple with quick and dirty. Simple Design is disciplined. Quick and dirty skips tests, ignores duplication, and produces spaghetti. They are opposites.
  • Over-engineering. Adding layers, patterns, and abstractions “for flexibility” is the enemy of Simple Design. Flexibility should be earned by demonstrated need.
  • Using simple as an excuse to skip abstraction. When a genuine need for abstraction appears (three similar features, two database types), Simple Design requires you to introduce it. It is not anti-abstraction; it is anti-premature-abstraction.
  • Applying it to genuinely complex domains. Some domains (avionics, tax law, molecular modelling) are inherently complex. Simple Design does not deny complexity; it refuses to add unnecessary complexity on top.
  • Rejecting all patterns. Patterns are tools. Simple Design uses them when they clarify intent and remove duplication, not when they impress readers.

Anti-pattern: A developer who says “we might need this later” is usually wrong. Track how often “later” actually arrives. Most teams find it is under 20% of the time.

NZ context

Fixed-price contracts are common in the New Zealand market, especially for government and SME engagements. In these contracts, every hour of unnecessary engineering is an hour that eats margin or burns budget. Simple Design protects both the vendor and the client against over-engineering that feels professional but delivers no business value.

New Zealand teams are often smaller than their international counterparts. A team of four developers cannot afford the maintenance overhead of a complex architecture designed for a team of forty. Simple Design keeps the codebase approachable so that any team member can safely modify any part of the system.

Career level guidance

Level Focus Milestones
Senior Apply the four rules in daily work; challenge over-engineering in review; refactor toward simplicity Can defend a simple design against demands for premature abstraction; consistently produces code that juniors can read and modify
Test Lead Ensure testability does not drive unnecessary complexity; coach the team on YAGNI; review designs for simplicity Identifies speculative generality during design review; measures and reports on code complexity metrics; secures stakeholder trust in lean designs

Tip for test leads: Cyclomatic complexity and lines of code are useful proxies, but the best test of Simple Design is a junior developer explaining the code back to you. If they can, it reveals intent. If they cannot, it is not simple yet.

← Back to Agile Techniques