Back to Blog

Clean Architecture

February 20, 20263 min
Clean ArchitectureSOLID PrinciplesSoftware Design
Clean Architecture

Clean Architecture

Clean Architecture Nedir?

Clean Architecture, iş mantığının (business logic):

  • Framework’lerden
  • Veritabanından
  • UI’dan
  • 3rd party servislerden

bağımsız olması gerektiğini savunan bir mimari yaklaşımdır.

Amaç: İş kurallarını dış dünyadan korumak.

Temel Amaçlar

1. Framework Bağımsızlığı

Express → Fastify geçsen bile iş mantığı değişmez.

2. Test Edilebilirlik

DB, HTTP server veya UI olmadan unit test yazabilirsin.

3. UI Bağımsızlığı

Web, mobile, CLI aynı use-case’i kullanabilir.

4. Database Bağımsızlığı

MongoDB’den PostgreSQL’e geçmek mimariyi bozmaz.

5. Dış Servis Bağımsızlığı

Mail sağlayıcısı değişirse domain etkilenmez.

Katmanlar

┌───────────────────────────────┐
│       Entities (Domain)       │  ← En iç (En stabil)
└──────────────┬────────────────┘
               │
┌──────────────┴────────────────┐
│        Use Cases (App)        │
└──────────────┬────────────────┘
               │
┌──────────────┴────────────────┐
│      Interface Adapters       │
└──────────────┬────────────────┘
               │
┌──────────────┴────────────────┐
│    Frameworks & Drivers       │ ← En dış (En değişken)
└───────────────────────────────┘

Dependency Rule

Dış katmanlar iç katmanlara bağımlı olabilir. İç katmanlar dış katmanlara bağımlı olamaz.

Bu Clean Architecture’ın en kritik kuralıdır.

1. Entities (Domain Layer)

  • Saf iş kuralları
  • Framework bağımlılığı yok
  • Express, DB, Logger bilmez

Örnek:

  • User
  • Order
  • Product

Bu katman en stabil katmandır.

2. Use Cases (Application Layer)

  • “Ne olacak?” sorusunun cevabı
  • İş akışlarını tanımlar
  • Repository interface bilir
  • DB implementasyonu bilmez

Örnek:

  • CreateUser
  • PayOrder
  • ResetPassword

3. Interface Adapters

  • Controller
  • Presenter
  • Gateway
  • Repository implementasyonu

Use-case ile dış dünya arasında çevirmen görevi görür.

4. Frameworks & Drivers

  • Express
  • MongoDB
  • Redis
  • React
  • Mail servisleri

En dış ve en değişken katmandır.

SOLID Principles

Clean Architecture genelde SOLID prensipleri üzerine oturur.

S — Single Responsibility Principle (SRP)

Bir sınıf sadece bir sebepten dolayı değişmelidir.

✔ Test etmek kolay ✔ Kod okunabilir ✔ Değişiklik güvenli

User, Repository, EmailService, Logger ayrı olmalıdır.

O — Open / Closed Principle (OCP)

Sınıflar genişletmeye açık, değiştirmeye kapalı olmalı.

Yeni PaymentMethod eklemek için mevcut kodu değiştirmemeliyiz.

Bu sayede:

  • Risk azalır
  • Regression azalır
  • Kod stabil kalır

L — Liskov Substitution Principle (LSP)

Alt sınıf, üst sınıfın yerine sorunsuz kullanılabilmelidir.

Square, Rectangle’dan extend edip davranışı bozuyorsa LSP ihlali vardır.

Çözüm:

  • Composition kullan
  • Doğru abstraction tasarla

I — Interface Segregation Principle (ISP)

Kimse kullanmadığı metodlara bağımlı olmamalı.

Büyük interface yerine küçük ve spesifik interface’ler.

✔ Readable ✔ Writable ✔ Aggregatable

D — Dependency Inversion Principle (DIP)

High-level modüller low-level modüllere değil, abstraction’a bağımlı olmalı.

UserService → IUserRepository (interface)
MongoUserRepository → IUserRepository implement eder

Bu sayede:

  • DB değişebilir
  • Kod değişmez

Clean Architecture Node.js Örnek Yapı

src/
├── domain/
├── application/
├── infrastructure/
└── interfaces/

Bu yapı sayesinde:

  • Domain saf kalır
  • Use-case bağımsız kalır
  • Infrastructure değişebilir
  • Controller sadece adaptör olur

Neden Bu Kadar Katman?

Küçük projede overkill olabilir.

Ama:

  • Proje büyüdüğünde
  • Mikroservis olduğunda
  • Takım büyüdüğünde
  • 3–5 yıl yaşayacak sistemde

Clean Architecture hayat kurtarır.

Clean Architecture vs Layered Architecture

Layered:

  • Controller → Service → Repository

Clean:

  • Domain merkezli
  • Dependency ters çevrilmiş
  • Framework en dışta

Büyük Resim

Client
  ↓
Controller
  ↓
Use Case
  ↓
Repository Interface
  ↓
Repository Implementation
  ↓
Database

Ama dependency yönü:

Database → Repository Impl → Use Case → Domain

Domain kimseyi bilmez.