Fundamentals 12 min read

Key Takeaways from Clean Architecture: A Practical Summary

This article distills the core concepts of Robert C. Martin’s Clean Architecture, covering layered design, SOLID principles, component cohesion and coupling rules, boundary strategies, the onion model, and why databases are merely infrastructure, all illustrated with concrete code examples and diagrams.

IT Learning Made Simple
IT Learning Made Simple
IT Learning Made Simple
Key Takeaways from Clean Architecture: A Practical Summary

1. Book Overview

Book: Clean Architecture by Robert C. Martin (Uncle Bob), published in 2017. The core theme is how to build simple, maintainable, and testable software architectures.

2. Core Idea: Layered Architecture

2.1 Layer Diagram

┌─────────────────────────────────────────────────┐
│               Presentation Layer                │
│        (Controllers, Gateways, UI)              │
├─────────────────────────────────────────────────┤
│                 Use‑case Layer                  │
│          (Application Business Rules)            │
├─────────────────────────────────────────────────┤
│                  Domain Layer                   │
│          (Enterprise Business Rules)            │
├─────────────────────────────────────────────────┤
│               Infrastructure Layer              │
│          (Frameworks, Drivers, DB)             │
└─────────────────────────────────────────────────┘

2.2 Core Principles

The dependency direction is always inward:

Presentation layer depends on the Use‑case layer; the Use‑case layer does not know about the Presentation layer.

Use‑case layer depends on the Domain layer; the Domain layer does not know about the Use‑case layer.

Domain layer has no dependencies on any other layer.

Key point: Dependencies may only point inward; outward dependencies are prohibited.

3. SOLID Principles

3.1 Single Responsibility Principle (SRP)

Definition: A class should have only one reason to change.

Bad example:

// Violates SRP: class has multiple reasons to change
class User {
    void saveUser() { /* database operation */ }
    void sendEmail() { /* email sending */ }
    void generateReport() { /* report generation */ }
    void calculateSalary() { /* salary calculation */ }
}

Correct example:

// Each class has a single responsibility
class UserRepository { void saveUser() { } }
class EmailService { void sendEmail() { } }
class ReportGenerator { void generateReport() { } }
class SalaryCalculator { void calculate() { } }

3.2 Open/Closed Principle (OCP)

Definition: Software entities should be open for extension but closed for modification.

Bad example: Adding a new payment method requires modifying existing code.

// Bad: modify code to add new functionality
class PaymentService {
    void pay(String type) {
        if (type.equals("alipay")) { /* Alipay logic */ }
        else if (type.equals("wechat")) { /* WeChat logic */ }
        // Add new payment? Change here!
    }
}

Correct example: Extend via new classes that implement a common interface.

interface Payment { void pay(); }
class Alipay implements Payment { void pay() { } }
class WechatPay implements Payment { void pay() { } }
class NewPay implements Payment { void pay() { } }

3.3 Liskov Substitution Principle (LSP)

Definition: Subtypes must be replaceable for their base types.

Bad example: A Square class inherits from Rectangle and overrides setWidth in a way that breaks the rectangle contract.

// Square violates LSP
class Rectangle { void setWidth(double w); void setHeight(double h); }
class Square extends Rectangle {
    void setWidth(double w) { this.width = w; this.height = w; // violates LSP
    }
}

Solution: Use an interface that represents the shape.

interface Shape { double getArea(); }

3.4 Interface Segregation Principle (ISP)

Definition: Clients should not be forced to depend on interfaces they do not use.

Fat interface example:

interface Worker {
    void work();
    void eat();
    void sleep();
    void code();
    void attendMeeting();
}
class Robot implements Worker {
    void work() { }
    void eat() { } // Robot does not need to eat
    void sleep() { } // Robot does not need to sleep
    void code() { }
    void attendMeeting() { }
}

Correct approach: Split the interface into focused ones.

interface Workable { void work(); void code(); }
interface Manageable { void attendMeeting(); }
interface Sustainable { void eat(); void sleep(); }
class Robot implements Workable { void work() { } void code() { } }

3.5 Dependency Inversion Principle (DIP)

Definition: High‑level modules should not depend on low‑level modules; both should depend on abstractions.

Bad example: OrderService directly uses a concrete MySQLDatabase.

class OrderService {
    private MySQLDatabase db; // direct concrete dependency
    void saveOrder(Order order) { db.save(order); }
}

Correct example: Depend on a Database interface.

interface Database { void save(Object obj); }
class MySQLDatabase implements Database { void save(Object obj) { } }
class MongoDatabase implements Database { void save(Object obj) { } }
class OrderService {
    private Database database; // depends on abstraction
    void saveOrder(Order order) { database.save(order); }
}

4. Component Principles

4.1 Component Cohesion Principles

REP (Reuse/Release Equivalence Principle): Component granularity equals reuse and release granularity.

CCP (Common Closure Principle): Classes that change together should be packaged together.

CRP (Common Reuse Principle): Do not force users to depend on unnecessary things.

4.2 Component Coupling Principles

ADP (Acyclic Dependencies Principle): Components must not have cyclic dependencies.

SDP (Stable Dependencies Principle): Dependencies should point toward stable components.

SAP (Stable Abstractions Principle): Stable components should be abstract.

5. Boundary Definition

5.1 What Is a Boundary

A boundary separates software elements.

┌────────────┐    ┌────────────┐
│   Business │    │   Database │
│   Rules   │←→│            │
└────────────┘    └────────────┘
      ↑
   Boundary line

5.2 Boundary Types

Source‑code level: module/package boundaries (e.g., Java package).

Deployment level: component boundaries (e.g., JAR/DLL).

Process level: service boundaries (e.g., micro‑service).

Physical level: system boundaries (stand‑alone system).

5.3 Boundary Strategy

“Draw early, bind late”. Define boundaries early, defer concrete implementation decisions. Avoid premature micro‑service or technology choices; first define clear boundaries, then decide the implementation.

6. Clean Architecture Onion Model

6.1 Model Diagram

┌─────────────────────┐
                │   Presentation      │
                │   Controllers        │
                │   Presenter          │
                └──────────┬──────────┘
                           │
                ┌──────────▼──────────┐
                │      Use‑case       │
                │   Use Cases         │
                │   Interactors       │
                └──────────┬──────────┘
                           │
                ┌──────────▼──────────┐
                │       Domain        │
                │   Entities          │
                │   Domain Objects    │
                └──────────┬──────────┘
                           │
                ┌──────────▼──────────┐
                │   Infrastructure    │
                │   Interfaces        │
                │   External Systems  │
                └─────────────────────┘

6.2 Core Points

The domain layer is at the core and does not depend on anything.

The use‑case layer orchestrates domain objects to implement scenarios.

The presentation layer handles external input and output.

The infrastructure layer implements interfaces and connects to external systems.

7. Database Is Just a Tool

7.1 Wrong View

Database = Architecture

7.2 Correct View

Database is just one kind of infrastructure.
Architecture should be driven by the business domain.
Database serves the architecture, not the other way round.

7.3 Implementation Example

// Domain model (core)
class User { private String name; private String email; }

// Repository interface defined in the domain layer
interface UserRepository {
    void save(User user);
    User findById(String id);
}

// JPA implementation in the infrastructure layer
class JPAUserRepository implements UserRepository {
    @Override
    public void save(User user) { /* JPA code */ }
    @Override
    public User findById(String id) { /* JPA code */ return null; }
}

8. Web Is Not the Center

8.1 Wrong Architecture

Web → Business Logic → Database

Is Web the center? No!

8.2 Correct Architecture

┌──────────┐
│   Web    │ ← one kind of presentation layer
├──────────┤
│   CLI    │ ← also possible presentation layer
├──────────┤
│   API    │ ← also possible presentation layer
└──────────┘
   ↓
┌──────────────────┐
│   Use‑case layer │
└──────────────────┘
   ↓
┌──────────────────┐
│   Domain layer   │
└──────────────────┘

8.3 Key Points

Presentation layer is only a way of input/output.

Core business logic should not know about the presentation layer.

The same domain model can be attached to different presentation layers.

9. Summary of Clean Architecture

Separate concerns by layering responsibilities.

Dependencies point inward, toward abstractions.

Clear boundaries are defined.

Domain layer is the most stable.

Business logic is testable because it does not depend on external details.

Clean Architecture is not a silver bullet, but it is a proven method for building maintainable, testable, and extensible software.
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Clean Architecturelayered architecturesoftware designdependency inversionSOLID
IT Learning Made Simple
Written by

IT Learning Made Simple

Learn IT: using simple language and everyday examples to study.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.