Skip to content

Coding Architecture: SOLID & Clean Design

Coding Architecture: SOLID & Clean Design

Great coding architecture ensures that your codebase is maintainable, testable, and adaptable to change over time.

πŸ—οΈ 1. SOLID Principles

The five foundational principles of object-oriented design.

  • S: Single Responsibility Principle (SRP): A class should have only one reason to change.
  • O: Open/Closed Principle (OCP): Software entities should be open for extension but closed for modification.
  • L: Liskov Substitution Principle (LSP): Subclasses should be substitutable for their base classes without breaking the application.
  • I: Interface Segregation Principle (ISP): Clients should not be forced to depend on interfaces they do not use.
  • D: Dependency Inversion Principle (DIP): Depend on abstractions, not on concretions. High-level modules should not depend on low-level modules.

πŸš€ 2. Clean Architecture (Hexagonal/Onion)

A layered approach where the Domain (Entities) sits at the center, surrounded by Use Cases, Adapters, and finally External Systems (DB, API, UI).

  • The Rule: Dependencies only point inward.
  • Benefits: The core business logic is independent of the UI, database, or external frameworks.

πŸ“Š 3. Domain-Driven Design (DDD)

Focus on the core domain and domain logic. It uses a Ubiquitous Language that both technical and non-technical stakeholders understand.

  • Aggregate Roots: A cluster of objects treated as a single unit for data changes.
  • Value Objects: Objects that are defined by their attributes rather than a unique identity (e.g., Money, Address).

πŸ› οΈ 4. Gang of Four (GoF) Patterns: The Complete List

The 23 original patterns are divided into three categories based on their purpose.

Creational Patterns (Object Creation)

NamePurpose
Factory MethodDefine an interface for creating an object, but let subclasses decide which class to instantiate.
Abstract FactoryCreate families of related objects without specifying their concrete classes.
BuilderConstruct complex objects step-by-step.
SingletonEnsure a class has only one instance and provides a global access point.
PrototypeCopy existing objects without making your code dependent on their classes.

Structural Patterns (Object Assembly)

NamePurpose
AdapterAllow incompatible interfaces to work together (The β€œBridge” between systems).
BridgeSplit a large class into two separate hierarchies: Abstraction and Implementation.
CompositeCompose objects into tree structures to represent part-whole hierarchies.
DecoratorAttach new behaviors to objects by placing them inside wrapper objects.
FacadeProvide a simplified interface to a complex library or framework.
FlyweightShare common parts of state between multiple objects to save RAM.
ProxyProvide a substitute or placeholder for another object to control access.

Behavioral Patterns (Communication)

NamePurpose
Chain of ResponsibilityPass requests along a chain of handlers.
CommandTurn a request into a stand-alone object containing all information about the request.
IteratorTraverse elements of a collection without exposing its underlying representation.
MediatorRestrict direct communications between objects and force them to collaborate via a mediator.
MementoSave and restore the previous state of an object without revealing its implementation.
ObserverDefine a subscription mechanism to notify multiple objects about events.
StateLet an object alter its behavior when its internal state changes.
StrategyDefine a family of algorithms and make them interchangeable.
Template MethodDefine the skeleton of an algorithm in the superclass but let subclasses override steps.
VisitorSeparate algorithms from the objects on which they operate.
InterpreterA way to include language elements in a program.

πŸ’‘ Best Practices

  1. DRY (Don’t Repeat Yourself): Avoid logic duplication across the codebase.
  2. KISS (Keep It Simple, Stupid): Avoid over-engineering. If a simple solution works, use it.
  3. YAGNI (You Ain’t Gonna Need It): Don’t add features until they are actually needed.
  4. TDD (Test-Driven Development): Write tests first to drive the design and ensure reliability.