C# Örneğiyle: Katmanlı Mimari de Ne?

Bu yazı ilk olarak Medium'da yayımlanmıştır.

Her projemizde veya her fikrimizde ilk bu canlanır: “Nasıl yapsak? Veri buradan gelir, bunu buradan set ederim, diğer tarafa implement etmek kolay ama sanki şurada bir sorun var…”

Günün sonunda bir şekilde kod yazmaya başlıyoruz. Fakat özellikle konuya yeni olan arkadaşlara katmanlı mimariyi dilim döndükçe anlatmak istiyorum.

Sürç-i lisan edersem, affola.

Hangi makarnayı seversin? Spagetti mi, Lazanya mı?

Spagetti vs Lazanya

Spagetti hızlıdır ama yedikçe makarnalar iç içe geçer. Lazanya ise kat kat yapılır; unu ayrı, kıyması ayrı, fırını ayrı… uğraştırır ama çok lezzetlidir. İşte koddaki lezzet de bu olmalı: katmanlı mimari ile unu ayrı, kıymayı ayrı hazırlayıp lezzetli bir ürün çıkaracağız.

Katmanlı mimari için çokça yaklaşım var (N-Tier, Onion vb.). Hepsinin ortak noktası: yapıları ayır, SOLID prensiplerini uygula, herkes kendi işini yapsın (single responsibility) ve alt-üst ilişkilerini koru.

Mahşerin üç atlısı: Presentation, Business, Data

Bir uygulamada talep edilen şeyler bellidir: bir iş kuralı vardır, veriler kayıt edilir ve kullanıcıya gösterilir. Örnek: öğretmenleri ve derslerini yöneten bir Öğretmen Bilgi Sistemi (ÖBS) düşünelim.

Kaynak kodları: github.com/eniskurtayyilmaz/TeacherManagement

  1. Kullanıcıya bir şeyler göstermeliyiz — Sunum Katmanı (Presentation Layer).
  2. Verileri gelişigüzel koymayız, kontrol gerekir — İş Katmanı (Business Layer).
  3. Veriyi nerede tutacağız? — Veri Katmanı (Data Layer).

En önemli nokta: tek bir controller içine spagetti tarzı upuzun kod yazmamak. Yani sunum katmanında DbContext'i çağırıp hem validation hem CRUD yapmayacağız.

Asla böyle spagetti kod yazmıyoruz — Single Responsibility ilkesine aykırı

Asıl amacımız yapıları ayırmak:

Mahşerin Üç Atlısı: Sunum, İş, Veri katmanı

1. İşleme ait web isteği parametreleri Presentation katmanında bir model olarak tanımlanmalı (ör. TeacherWebInsertRequestModel).

2. Gelen model bir iş kuralına göre kontrol edilecek veya kaydedilecekse bu Business katmanında yapılır. Presentation modelini Business'a taşımak için katmana özgü RequestDTO/ResponseDTO nesneleri oluşturulur ve Presentation yalnızca Interface üzerinden erişir.

Business katmanındaki kod bloğu
Presentation katmanından Business katmanına transfer

3. Verileri bir veri tabanına veya servise yazacaksak bu Data katmanında yapılır. Data katmanına da yalnızca Interface üzerinden erişilir.

Data katmanındaki Teacher nesnesi — tablonun modeli
Data katmanına erişimde kullanılacak metotlar

Repository kısmını GenericRepository yaklaşımıyla yazarsanız, bugün X veri tabanından yarın Y veri tabanına geçişi bile rahatça yönetebilirsiniz.

Business katmanından Data katmanına geçiş

Buradaki asıl mesele: üst katmana ait veri modelinin alt katmana göre hazırlanması ve veri modellerinin dönüşümü.

“İyi de neden modeller yaratıyoruz, doğrudan veri tabanına gitsek olmaz mı?” Olmaz — çünkü katmanları ayırmakla mükellefiz ve bu yönetimi kolaylaştırır.

Projeye öğretmene ait dersleri de ekleyelim ve faydasını görelim:

1. Data katmanında bir Course modeli oluşturup CRUD işlemlerini yapalım.

Course modelinin içeriği
Course nesnesinin veri tabanı CRUD işlemleri

2. Business katmanında iş kuralını yönetelim: her dersin bir öğretmeni olmalı, o hâlde dersi kaydederken önce öğretmenin varlığını kontrol edelim.

Course Business katmanında Teacher kontrolü

3. Business katmanındaki derse ait dönüş nesnesine öğretmen bilgisini de ekleyebiliriz.

Course Business katmanında ResponseDTO

4. Presentation katmanında ise sadece gerekli bilgiyi döneriz (ör. “… derse … öğretmene kaydınız yapılmıştır”).

Presentation katmanında InsertCourse response modeli

Kaynak kodları: github.com/eniskurtayyilmaz/TeacherManagement