Clean Architecture, Robert C. Martin tarafindan formule edilen ve bağımlılık kuralina dayanan bir yazılım yapisidir: kaynak kod bağımlılıkları ic ice degil, disa doğru yönlendirilmelidir. Domain ve use case'ler merkezde, framework ve veritabanı dis halkada kalir. Teori güçlü olsa da pratikte asiri soyutlama, gereksiz arayüz patlamasi ve geliştirme hizi kaybi riski vardir. Denge, prensipleri ihtiyaca gore uygulamaktir.
Halkalar ve bağımlılık kurali
Ic halka entity'ler ve enterprise business rules icerir. Orta halka use case'leri orkestra eder. Dis halkalar interface adapter'lari (controller, presenter, gateway) ve framework/driver'lari barindirir. Bağımlılık kurali: ic halkadaki hicbir sey dis halkayi bilmez.
Entities -> Use Cases -> Interface Adapters -> Frameworks
(Dependencies point inward only)
Pragmatik Clean Architecture
Her repository icin arayüz yazmak küçük projede gereksiz olabilir. Pragmatik yaklaşım: domain ve application katmanlarini koru, infrastructure detaylarini adapter'larla izole et, ancak henuz degismeyen altyapi icin dogrudan somut implementasyon kabul et. Refactoring ihtiyaci dogdugunda arayüz cikarilir.
- YAGNI: Ihtiyaç olmayan soyutlama ekleme.
- Stable abstractions: Değişen tarafta somut, stabil tarafta arayüz.
- Thin adapters: Controller ve repository impl ince kalmali.
- Rich domain: Is mantigi entity'de, handler'da degil.
Use case odaklı tasarım
Her use case açık bir sınıf veya handler olarak modellenir. CreateOrder, GetProductList gibi isimler domain dilini yansitir. Use case input/output port arayuzlerini kullanır; output port presenter veya response mapper ile implement edilir.
Input ve output port'lar
Input port use case arayuzudur. Output port dis dunyaya veri sunar (örneğin IEmailSender). Bu ayrim testlerde output port'u fake ile degistirmeyi kolaylastirir.
public interface IPlaceOrderUseCase
{
Task<PlaceOrderResult> Execute(PlaceOrderCommand command);
}
public sealed class PlaceOrderHandler : IPlaceOrderUseCase
{
// domain + repository port
}
Framework bagimsizligi
Clean Architecture'in vaadi framework degistirebilme esnekligidir. Gercekte çoğu proje ASP.NET Core ve EF Core ile yillarca kalir. Yine de domain'in HttpContext veya DbContext bilmemesi test edilebilirlik ve domain odaklı dusunmeyi destekler. Framework bagimliligi sadece en dis halkada toplanir.
Test edilebilirlik kazanimlari
Domain ve use case katmanları dis bağımlılık olmadan test edilir. Mock yerine fake implementasyon tercih edilebilir. Entegrasyon testleri adapter katmaninda çalışır. Test hizi ve guvenilirligi artar cunku domain testleri milisaniyeler icinde biter.
Asiri soyutlamadan kacinma
Her sınıf icin interface, her işlem icin factory, her DTO icin mapper kombinasyonu kod tabanini sisirir. Code review sorusu: Bu soyutlama gerçek bir değişim ihtiyacini mi karsiliyor? Gelecekteki olasi ihtiyaç icin bugun maliyet odemek teknik borc uretebilir.
- Tek implementasyonlu arayuzleri birlestir veya kaldir
- Generic repository anti-pattern'inden kaçın
- Use case basina ayri DTO yerine paylasilan model düşün
- Mapping katmanini sade tut
Clean Architecture ve DDD birlikteligi
Aggregate, value object ve domain event Clean Architecture'in entity halkasinda yasar. Use case handler transaction sınırı ve orkestrasyonu yönetir. Repository arayüzü domain halkasinda tanimlanir, implementasyon infrastructure'dadir. Bu birlesim kurumsal projelerde yaygın bir başarı kalibidir.
CQRS ve read model istisnasi
Okuma tarafinda domain entity yuklemek gereksiz olabilir. Query handler dogrudan read model veya SQL projection kullanabilir. Bu Clean Architecture'in katı yorumuna aykiri gorunebilir ancak performans gereksinimi pragmatik istisna olarak dokumante edilmelidir.
Command ve query ayirimi
Command handler domain kurallarini uygular. Query handler yan etkisiz ve optimize edilmis okuma yapar. Ayni veritabanı veya ayri read store kullanılabilir.
Cross-cutting concern dengesi
Loglama, cache ve transaction pipeline veya decorator ile eklenir. Ancak her use case etrafina on decorator sarmalamak okunabilirligi dusurur. MediatR pipeline veya aspect-oriented middleware dengeli çözüm sunar.
Proje yapisi ornegi
MyApp.Domain/ # Entities, value objects, domain events
MyApp.Application/ # Use cases, interfaces (ports)
MyApp.Infrastructure/ # EF, email, bus adapters
MyApp.Api/ # ASP.NET Core host
Performans ve karmasiklik maliyeti
Her katman arasi mapping allocation ve gecikme ekler. Profiling ile darbogaz tespit edilmeden katman birlestirme yapilmamali. Okuma yolunda bypass, yazma yolunda tam domain modeli kullanmak yaygın bir denge stratejisidir.
Ekip olgunlugu ve öğrenme egrisi
Clean Architecture yeni geliştiriciler icin öğrenme maliyeti tasir. Onboarding dokumani, örnek use case ve mimari karar kayitlari (ADR) bu maliyeti dusurur. Küçük ekipte basit katmanli yapı ile baslayip olgunluk arttikca halka modelini sikilastirmak makul bir yoldur.
Legacy entegrasyon
Mevcut sistemler facade ve anti-corruption layer ile dis halkaya alinir. Yeni use case'ler ic halkada geliştirilir. Zamanla legacy facade'un sorumlulugu azalir.
Yaygın anti-pattern'ler
Anemic domain: entity bos, use case her seyi yapar. God use case: tek handler bin satir. Leaky use case: handler icinde SQL string. Circular dependency: port tanimlari birbirine bağımlı. Framework in domain: HttpContext entity icinde.
Ne zaman tam Clean Architecture?
Uzun omurlu kurumsal uygulama, sik değişen is kurallari, yüksek test gereksinimi ve çoklu delivery kanali (API, batch, mesaj) varsa tam model deger üretir. CRUD admin paneli veya kisa omurlu MVP icin sadeleştirilmis varyant yeterlidir.
Metrikler ve kalite kapilari
Cyclomatic complexity use case basina izlenir. Domain test coverage hedefi belirlenir. Mimari testler bağımlılık ihlalini CI'da bloklar. Bu metrikler soyutlama seviyesini tartismayi veriye dayandirir.
Özet denge formulu
Clean architecture dengesi: ic halkayi koru, dis halkayi pragmatik tut, gereksiz arayüz uretme, read path'te istisna tanı, test ve mimari kurallarla sınırları zorla, ekip olgunluguna gore basit basla. Amac mükemmel diyagram degil, degisebilir ve anlasilir is mantigi merkezidir.
Üretim ortaminda mimari disiplin
Mimari kararlar yalnizca tasarım dokumaninda kalmamali; CI pipeline, code review checklist ve otomatik analiz araclari ile gunluk geliştirme akisina gomulmelidir. Bağımlılık ihlali, modül sınırı asimi veya katman ihlali iceren pull request'ler merge edilmeden once duzeltilmelidir. Bu disiplin olmadan en iyi diyagramlar bile zamanla erozyona ugrar.
Metrikler ve geri bildirim
Modül basina değişim sikligi, test coverage, cyclomatic complexity ve build sure metrikleri mimari sagligi gösterir. Ani complexity artisi veya test coverage dususu refactoring ihtiyacinin sinyalidir. Teknik liderlik bu metrikleri sprint review'da is degeri ile birlikte degerlendirmelidir.
Incident post-mortem'lerinde kok neden analizi mimari sınırları da kapsamali. Cross-modül veya cross-layer coupling iceren hatalar ADR veya mimari backlog'a donusturulmelidir. Tekrarlayan ihlaller otomatik lint kurallari ile onlenir.
Üretim ortaminda mimari disiplin
Mimari kararlar yalnizca tasarım dokumaninda kalmamali; CI pipeline, code review checklist ve otomatik analiz araclari ile gunluk geliştirme akisina gomulmelidir. Bağımlılık ihlali, modül sınırı asimi veya katman ihlali iceren pull request'ler merge edilmeden once duzeltilmelidir. Bu disiplin olmadan en iyi diyagramlar bile zamanla erozyona ugrar.
Metrikler ve geri bildirim
Modül basina değişim sikligi, test coverage, cyclomatic complexity ve build sure metrikleri mimari sagligi gösterir. Ani complexity artisi veya test coverage dususu refactoring ihtiyacinin sinyalidir. Teknik liderlik bu metrikleri sprint review'da is degeri ile birlikte degerlendirmelidir.
Incident post-mortem'lerinde kok neden analizi mimari sınırları da kapsamali. Cross-modül veya cross-layer coupling iceren hatalar ADR veya mimari backlog'a donusturulmelidir. Tekrarlayan ihlaller otomatik lint kurallari ile onlenir.