Clean Architecture - Deep Dive

Back to Software Development Index

เชื่อว่าในการพัฒนาซอฟต์แวร์นั้น ความเข้าใจในเรื่องสถาปัตยกรรม (Software Architecture) มีความสำคัญอย่างยิ่ง เพราะนอกจากจะช่วยออกแบบระบบได้ดียิ่งขึ้น ยังเป็นการเปิดมุมมองต่อแนวคิดเบื้องหลังของสถาปัตยกรรมเหล่านี้อีกด้วย เพื่อให้นำมาปรับใช้ได้เหมาะสมกับงาน

What is Clean Architecture?

Clean Architecture เป็นการอ้างอิงจากบทความของ Robert C. Martin แม้ว่าบทความนั้นจะมีอายุมากกว่า 10 ปีแล้ว แต่แนวคิดก็ยังนับว่าน่าสนใจไม่น้อยเลยทีเดียว

สถาปัตยกรรมนี้ให้ความสำคัญกับ Separation of Concern คือมีการแบ่ง layer การทำงานของซอฟต์แวร์เป็นชั้นๆ ซึ่งในแต่ละชั้น layer จะทำงานในขอบเขตของตัวเองไม่ปะปนกัน

The Dependency Rule Diagram

ในแผนภาพสะท้อนหลักการ The Dependency Rule โดย:

  • วงกลมด้านนอก จะเกี่ยวข้องกับการติดต่อประสานเครื่องไม้เครื่องมือต่างๆ สามารถปรับเปลี่ยนได้ตลอด
  • วงกลมด้านใน จะเป็นการกำหนดนโยบายซึ่งเกี่ยวข้องกับ business โดยตรง จึงไม่ได้ปรับเปลี่ยนบ่อย

นอกจากนี้ยังกล่าวว่า source code dependencies can only point inwards คือวงภายในจะต้องไม่รับรู้และไม่พึ่งพาอาศัยโค้ดจากวงภายนอก แต่วงนอกพึ่งพาอาศัยวงภายในตามลูกศร depend on

Layer-by-Layer Analysis

เดี๋ยวเรามาลงรายละเอียดในแต่ละวงกัน เริ่มจากด้านนอกเข้าไปด้านใน

🔵 Frameworks and Drivers (Outermost Layer)

เป็นส่วนที่จัดการกับ Framework และติดต่อกับเครื่องมือภายนอกอื่นๆ ด้วย driver

Characteristics:

  • อาจไม่ได้เขียนโค้ดมาก
  • เป็นการลงรายละเอียดที่จำเพาะ (specific)
  • ติดต่อกับ database ตัวไหน
  • จะใช้ Web Framework อะไร

Examples:

  • Database drivers (PostgreSQL, MongoDB)
  • Web frameworks (Express, Django, Spring)
  • External APIs
  • UI frameworks

🟢 Interface Adapters

ใช้ในการแปลงข้อมูล (convert data) ให้อยู่ใน format ที่เหมาะสม ให้วงในและนอกสื่อสารกันได้

แบ่งได้เป็นหมวดหลักๆ ดังนี้:

Presenters

  • ใช้จัดการ UI logic หรือ states
  • แปลงให้แสดงผลได้เหมาะสม
  • Format ข้อมูลสำหรับการแสดงผล

Controllers

  • ใช้จัดการ input/output จากระบบภายนอก
  • รับจาก UI, external services
  • รับ request มา validate/process ตาม business logic
  • เป็นจุดเข้าสู่ use cases

Gateways

  • อาจเรียกว่า repository หรือ data access layer
  • ใช้จัดการ communication จาก data source
  • ทำ data access operation
  • แปลงข้อมูลระหว่าง external storage กับ domain entities

🟡 Application Business Rules (Use Cases)

เป็นการกำหนด rule ที่จำเป็น (แต่ยังไม่ใช่ core-business-rule)

Use Case:

  • บอกว่า application มี function ใช้ทำอะไรได้บ้าง
  • กำหนดว่าควรเรียก Controller/Gateway มาใช้ในแต่ละ use case
  • Orchestrate flow ของ business logic
  • ไม่ขึ้นกับ framework หรือ infrastructure

Examples:

  • CreateUser
  • ProcessPayment
  • GenerateReport
  • SendNotification

🔴 Enterprise Business Rules (Entities)

ส่วนนี้จะกำหนด core-business-rule

Characteristics:

  • Model/entity ที่ใช้เก็บ data structure
  • มีการเปลี่ยนแปลงน้อยที่สุด
  • ไม่ได้รับผลกระทบจากการเปลี่ยนแปลงของภายนอกมาก
  • Pure business logic
  • ไม่มี dependencies ใดๆ

Examples:

  • User entity with validation rules
  • Order with business calculations
  • Product with pricing rules

Benefits of Clean Architecture

1. Independence

  • Framework Independence - Not tied to any framework
  • Database Independence - Business rules don’t know about DB
  • UI Independence - Can change UI without changing business rules
  • External Agency Independence - Business rules don’t depend on external systems

2. Testability

  • Business rules can be tested without UI, Database, Web Server, or external elements
  • Easy to write unit tests
  • Fast test execution

3. Flexibility

  • Easy to change one layer without affecting others
  • Can defer decisions about frameworks, databases, etc.
  • Easier to adapt to changing requirements

4. Maintainability

  • Clear boundaries between layers
  • Easy to understand system structure
  • Reduces technical debt

Implementation Guidelines

DO ✅

  • Keep business logic in the center
  • Define clear interfaces between layers
  • Use dependency inversion
  • Write tests for each layer
  • Keep entities pure (no framework dependencies)

DON’T ❌

  • Let outer layers influence inner layers
  • Put business logic in controllers
  • Make entities depend on infrastructure
  • Skip defining interfaces
  • Bypass layers

Common Pitfalls

  1. Anemic Domain Model

    • Entities with no behavior, only data
    • Business logic scattered in services
  2. Leaky Abstractions

    • Inner layers knowing about outer layer details
    • Database concerns in domain layer
  3. Over-engineering

    • Too many layers for simple applications
    • Unnecessary complexity
  4. Poor Interface Design

    • Interfaces that expose implementation details
    • Too granular or too coarse interfaces

When to Use Clean Architecture

Good Fit ✅

  • Large, complex applications
  • Long-term projects
  • Team with multiple developers
  • Applications that will evolve significantly
  • When testability is critical

Might Be Overkill ❌

  • Simple CRUD applications
  • Prototypes or MVPs
  • Small team/single developer
  • Short-lived projects
  • When time-to-market is critical

Real-World Example

E-commerce Order System

📦 Infrastructure Layer
   └─ PostgreSQL, Redis, SendGrid

🔌 Interface Adapters
   ├─ REST Controllers (OrderController)
   ├─ Presenters (OrderPresenter)
   └─ Gateways (OrderRepository, PaymentGateway)

⚙️ Use Cases
   ├─ CreateOrder
   ├─ ProcessPayment
   └─ NotifyCustomer

💎 Entities
   ├─ Order (with business rules)
   ├─ Product
   └─ Customer

Conclusion

Clean Architecture นี้จะเป็นประโยชน์กับผู้ที่เริ่มต้นศึกษาและต้องการออกแบบระบบที่สามารถ maintain ได้ในระยะยาว โดยเน้นการแยก business logic ออกจาก technical details


Related:

References: