Skip to content
Clean Architecture — Explained with Examples

Clean Architecture — Explained with Examples

DodaTech Updated Jun 15, 2026 2 min read

Clean Architecture organizes code into concentric layers where inner layers contain business rules and outer layers handle frameworks, UI, and infrastructure.

Clean Architecture, coined by Robert C. Martin, is also known as Hexagonal Architecture (Ports and Adapters) or Onion Architecture. Its core rule: dependencies point inward. Outer layers (UI, database, web) depend on inner layers (business logic), never the reverse.

Why Clean Architecture Matters

Frameworks and databases become obsolete or get replaced. If your business logic is tightly coupled to Django, Spring, or MySQL, replacing them means rewriting everything. Clean Architecture isolates business rules from infrastructure concerns, making the system adaptable and testable without frameworks.

Real-World Analogy

A company’s core operations (accounting, payroll) happen in a secure inner office. Visitors, deliveries, and contractors interact through a reception desk (interface). If the receptionist is replaced or the mail system changes, the core operations continue undisturbed. Clean Architecture is that inner office protected by well-defined interfaces.

Example: Clean Architecture Layers

# ---- Inner layer: Entities (enterprise business rules) ----
class Order:
    def __init__(self, items: list):
        self.items = items
        self.paid = False

    def total(self) -> float:
        return sum(item.price for item in self.items)

# ---- Inner layer: Use Cases (application business rules) ----
class CheckoutUseCase:
    def __init__(self, payment_gateway, order_repo):
        self.payment_gateway = payment_gateway  # interface
        self.order_repo = order_repo            # interface

    def execute(self, order):
        total = order.total()
        success = self.payment_gateway.charge(total)
        if success:
            order.paid = True
            self.order_repo.save(order)

# ---- Outer layer: Adapters (frameworks, UI, DB) ----
class StripePaymentGateway:  # implements payment interface
    def charge(self, amount):
        print(f"Charging ${amount} via Stripe")
        return True

class PostgresOrderRepository:  # implements repo interface
    def save(self, order):
        print(f"Saving order (${order.total()}) to Postgres")

# Wiring — done at composition root
repo = PostgresOrderRepository()
gateway = StripePaymentGateway()
use_case = CheckoutUseCase(gateway, repo)
use_case.execute(Order([Item("Laptop", 999)]))

Related Terms

CQRS, Repository Pattern, Dependency Injection, SOLID

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro