← All writing
HackerNoonMarch 2025

Enhance Code Architecture With SOLID

Good architecture is not code that works; it is code that can be extended, tested and maintained without a rewrite. The piece takes Robert C. Martin's five principles and treats them as tools for specific problems: lowering coupling so a change stays local, reducing the risk that a modification breaks something distant, and making a system straightforward to test and automate.

Each principle — single responsibility, open/closed, Liskov substitution, interface segregation and dependency inversion — is worked through with Swift examples rather than left as an acronym to recite.

Every section follows the same shape: a small, plausible piece of Swift that already violates the principle, an explanation of why that shape causes trouble as the code grows, and a revised version that fixes it. The violations are ordinary ones — a model object that also sends email, a payment function that grows another if-branch per provider, a subclass that can't honestly fulfil its parent's contract, an interface that forces a type to implement behaviour it doesn't have, a service wired directly to one database implementation.

The Liskov and interface-segregation examples sit next to each other on purpose, since both are about a type being asked to support more than it should — one through inheritance, the other through an interface — and the piece draws that line explicitly rather than leaving the two principles to blur together.

What's inside

  • Single responsibility, shown through a User type that also sends email, split so a separate EmailService owns that job and User is left holding only user data.
  • Open/closed, shown through a payment function built on branching per payment method, replaced by a PaymentMethod protocol so a new provider is added without touching the existing processor.
  • Liskov substitution, shown through an electric car forced to inherit a refuel() method it cannot honestly implement, resolved by giving refuelable and chargeable vehicles separate interfaces.
  • Interface segregation, shown through one transport interface that makes every vehicle implement driving, sailing and flying, split into role-specific protocols — with a short note on how this differs from the Liskov example.
  • Dependency inversion, shown through an order service constructed directly against a MySQL class, refactored to depend on a Database protocol so the concrete store can be swapped and replaced with a test double.
The takeaway

None of the five principles is presented as a rule to recite; each targets a specific way ordinary code degrades as it grows, and the running thread through all five examples is the same move — replace a direct dependency on one concrete shape with an abstraction that can vary.

See the Swift before/after code for all five SOLID fixes on HackerNoon ↗