Skip to content
DevPedia

Guide 4 of 4

How to review a software design

Practical questions for spotting unnecessary complexity, unclear responsibilities, and dependencies that make change harder.

Updated 2 min read

When designing or reviewing a component, these questions help you apply the general principles and SOLID without slipping into over-engineering. They’re grouped by symptom, not by principle: the same question can raise KISS and YAGNI at once.

Complexity (KISS)

  • Does this abstraction justify its cost — more files, more indirection — with a problem that exists today?
  • Could I implement the requirement more simply?
  • Does the pattern being used solve a real problem, or does it just make the design look more sophisticated?

Duplication (DRY)

  • Does the duplicated code really represent the same knowledge?
  • Should these pieces evolve together?
  • Would removing the duplication increase coupling?

Future requirements (YAGNI)

  • Is this feature actually needed?
  • Are we solving a known problem or a hypothetical one?
  • Is the cost of preparing for it now lower than the expected cost of changing it later?

Responsibilities (SoC / SRP)

  • Does this component have multiple independent reasons to change?
  • Does separating them actually improve cohesion, or does it just add indirection?

Coupling (composition, Demeter)

  • Does this component depend on another one’s internal details?
  • Are we navigating an object graph that should be encapsulated?
  • Is inheritance hiding coupling that composition would leave visible?

Contracts and substitution (LSP)

  • Can I replace this implementation with another one without the caller noticing?
  • Does this implementation demand more than the contract promises, or deliver less?

Interfaces (ISP)

  • Do the consumers of this interface actually use all of its methods?
  • Are there implementations throwing exceptions in methods that don’t apply to them?

Direction of dependencies (DIP)

  • Does the business logic depend on a concrete infrastructure detail?
  • Could I invert that dependency without introducing a premature abstraction?

None of these questions has a universal answer. The goal isn’t to tick every box, it’s to have the vocabulary to justify a design decision: to recognize when an abstraction is solving a real problem and when it’s only there because “that’s how it’s done”.

Share this guide

Search by concept, pattern or practice.