Bir Laravel projesini ilk açtığımda, tek bir “kullanıcı oluştur” işleminin yedi dosyaya yayıldığını gördüm: Controller, Request DTO, UseCase, Domain Entity, Repository Interface, Eloquent Repository ve iki yönlü bir Mapper. İçindeki tek iş kuralı, e-postanın benzersiz olmasıydı.
Bu, Clean Architecture’ın yanlış uygulanmış hâliydi — ama suç Clean Architecture’da değil. Suç, hangi projenin hangi disipline ihtiyacı olduğunu hiç sormamakta.
İki yaklaşım, kısaca
Katmanlı (layered) mimari tanıdık olandır: Controller → Service → Repository → veritabanı. Bağımlılıklar yukarıdan aşağı akar, en altta framework durur. Laravel’in kendisi de zaten budur — Eloquent bir active record, controller’lar HTTP’ye bağlı, her şey framework’e gömülü.
Clean Architecture (ve akrabaları hexagonal, onion) bağımlılık yönünü tersine çevirir: merkezde framework’ten habersiz domain durur, bağımlılıklar içeri doğru bakar. Veritabanı, HTTP, framework — hepsi en dıştaki halkada, birer detay. Domain, Laravel’in var olduğunu bilmez.
Fark felsefi değil, çok somut: katmanlı mimaride domain Eloquent’e bağımlıdır; Clean’de Eloquent domain’e bağımlıdır.
Clean Architecture neyi satın alır
Bedava değil, ama gerçek şeyler verir:
- Framework’ten bağımsız test. Domain kuralları, veritabanı olmadan, saf birim testlerle koşulur. Hızlı ve kırılgan değil.
- Framework’ün ömründen uzun domain. İş kuralları, Laravel sürümlerinden bağımsız yaşar. On yıllık bir domain, üç major framework upgrade’i görebilir.
- Birden çok teslim mekanizması. Aynı domain’i HTTP API, CLI komutu ve queue worker üzerinden çağırmak doğallaşır.
Karşılığında ödediğiniz de somut: her katman geçişinde mapping, daha çok dosya, daha çok dolaylılık. Tek satırlık bir kural için yedi dosya — yazının başındaki manzara.
Çoğu Laravel projesi için katmanlı yeter
Açık konuşayım: çoğu web uygulaması özünde CRUD’dur. Veriyi doğrula, kaydet, oku, göster. Böyle bir uygulamada Eloquent’e karşı “clean code” uğruna savaşmak, kazanılan değerden pahalıdır.
Laravel’i bir detay değil, bilinçle seçilmiş bir temel olarak kabul edin. Controller + Form Request + Eloquent model + ince bir service sınıfı — bu, projelerin büyük çoğunluğu için doğru ağırlıktır. Framework’ü kucaklamak bir ödün değil, bir karardır; tıpkı boring architecture gibi.
Yedi katmanlı bir CRUD ise spekülatif genelliğin mimari ölçekteki hâlidir: bugün olmayan bir karmaşıklık için bugünden vergi ödemek.
Clean Architecture ne zaman karşılığını verir
Disiplin, domain karmaşıklığı yüksek olduğunda gerçek getiri sağlar. Şu sinyaller varsa ciddiye alın:
- İş kuralları “kaydet/oku”nun çok ötesinde: çok adımlı hesaplamalar, durum makineleri, sektörel düzenlemeler.
- Bu kuralların framework’ten uzun yaşaması bekleniyor.
- Aynı domain birden fazla arayüzden besleniyor — API, CLI, mesaj kuyruğu, panel.
- Kural değişiklikleri sık ve riskli; veritabanına dokunmadan test edebilmek gerçek bir hız kazandırıyor.
Sigorta primlendirme, muhasebe, lojistik optimizasyonu — bu alanlarda Clean Architecture’ın dolaylılığı kendini öder. Bir blog ya da standart bir yönetim panelinde ödemez.
Hep ya da hiç değil
En sık atlanan nokta: bu bir ikili seçim değil. Aynı kod tabanında ikisi bir arada yaşayabilir.
Domain’in gerçekten karmaşık olduğu modülü — diyelim fiyatlandırma — Clean tarzı izole edin: saf domain, interface’le ayrılmış repository, framework’ten bağımsız testler. Geri kalan CRUD modüllerini düz bırakın: controller, Eloquent, ince service. Modüler monolitin sağladığı sınırlar bunu doğal kılar — her modül kendi ağırlığını taşır.
Mimari, projeye tek tip dağıtılan bir kural değil; karmaşıklığın yoğunlaştığı yere göre ayarlanan bir bütçedir.
Clean Architecture bir rozet değil, bir araç. Domain’iniz onun çözdüğü problemi yaşıyorsa paha biçilmez; yaşamıyorsa, tek satırlık bir kuralı yedi dosyaya bölen bir törenden ibaret.
Mimariyi domain seçer — moda değil.