Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

Projemi Katmanlı Mimari ile Düzenleyip Dependency Injection'ın Gücünden Nasıl Yararlandım?

thecoder

Üye
Katılım
14 Mart 2026
Mesajlar
10
Merhaba arkadaşlar, bugün sizlere özellikle orta ve büyük ölçekli projelerde hayat kurtaran, benim de artık vazgeçilmezim haline gelen bir yapıdan bahsedeceğim. Başlangıçta her şeyi controller'a doldurup "çalışıyor işte" dediğim günler geride kaldı. Proje büyüdükçe, bir fonksiyonda değişiklik yapmak için 500 satırlık bir dosyada gezmek, test yazmak imkansız hale geliyordu. İşte tam da bu noktada Controller > Service > Repository katmanlı mimarisi ve Dependency Injection imdadıma yetişti.

🔥 Neden Bu Yapıya Geçtim?

Aslında sebep basitti: spaghetti kod. Auth işlemleri, veritabanı sorguları, iş mantığı (business logic) hepsi aynı controller dosyasının içinde, birbirine girmiş vaziyetteydi. Bir bug'ı fixlemek, yeni bir özellik eklemek kabusa dönüşüyordu. Ayrıca, birim testi (unit test) yazmak neredeyse imkansızdı çünkü her şey birbirine sıkı sıkıya bağlıydı. "Tight Coupling" denen o illet işte.

Katmanlı mimari, bu karmaşayı ayrıştırmak ve her katmana tek bir sorumluluk vermek için birebir. Repository veritabanından sorumlu, Service iş kurallarından, Controller ise gelen HTTP isteğini alıp cevap dönmekten.

🏗️ Katmanları Nasıl Ayırdım?

Hemen basit bir Kullanıcı Yönetimi örneği üzerinden gidelim. Diyelim ki bir kullanıcının profil bilgilerini getireceğiz.

İlk katman Repository. Tek işi veritabanı ile konuşmak.
JavaScript:
// UserRepository.js
class UserRepository {
  constructor(databaseConnection) {
    this.db = databaseConnection;
  }

  async findById(userId) {
    // Sadece ve sadece DB sorgusu!
    return await this.db('users').where({ id: userId }).first();
  }

  async updateProfile(userId, updateData) {
    return await this.db('users').where({ id: userId }).update(updateData);
  }
}

Sonraki katman Service. İş mantığı burada. Repository'yi kullanır.
JavaScript:
// UserService.js
class UserService {
  constructor(userRepository, emailService) {
    this.userRepository = userRepository;
    this.emailService = emailService;
  }

  async getUserProfile(userId) {
    const user = await this.userRepository.findById(userId);
    if (!user) {
      throw new Error('Kullanıcı bulunamadı!');
    }
    // Belki burada kredi skoru kontrolü, yetki kontrolü gibi iş kuralları olacak.
    return user;
  }

  async updateUserProfile(userId, profileData) {
    // İş kuralları: Mail değiştiyse doğrulama gönder.
    const updatedUser = await this.userRepository.updateProfile(userId, profileData);
    if (profileData.email) {
      await this.emailService.sendVerificationEmail(updatedUser.email);
    }
    return updatedUser;
  }
}

En üst katman Controller. HTTP istek/cevap işleri burada.
JavaScript:
// UserController.js
class UserController {
  constructor(userService) {
    this.userService = userService;
  }

  async getProfile(req, res) {
    try {
      const userId = req.params.id;
      const userProfile = await this.userService.getUserProfile(userId);
      res.json({ success: true, data: userProfile });
    } catch (error) {
      res.status(404).json({ success: false, message: error.message });
    }
  }
}

💉 Dependency Injection (Bağımlılık Enjeksiyonu) Neden Altın Değerinde?

Yukarıdaki kodlara dikkat edin. UserService, UserRepository'yi constructor'ında parametre olarak alıyor. UserController da UserService'i parametre olarak alıyor. İşte bu, Dependency Injection (DI).

Faydaları:
1. Test Edilebilirlik: Unit test yazarken, gerçek veritabanı bağlantısı olan bir Repository yerine, taklit (mock) bir Repository objesini Service'in constructor'ına verebilirim. Aynı şekilde Controller'ı test ederken de mock Service kullanırım. Her şey birbirinden bağımsız test edilebilir!
2. Esneklik: Yarın öbür gün veritabanınızı MySQL'den PostgreSQL'e geçirmek isterseniz, sadece Repository katmanındaki sorguları değiştirirsiniz. Service ve Controller katmanları hiç etkilenmez.
3. Merkezi Yönetim: Bağımlılıklarınızı (Service, Repository vs.) merkezi bir yerden (bir Container) yönettiğinizde, yaşam döngülerini ve konfigürasyonlarını tek elden kontrol edersiniz.

🎯 Sonuç ve Düşüncelerim

Bu yapıya geçiş yapmak ilk başta biraz fazla dosya, biraz fazla soyutlama gibi gelebilir. Küçük projelerde gereksiz de olabilir. Ama projeniz büyümeye başladığı anda, özellikle ekip arkadaşlarınızla çalışırken, herkesin aynı yapıyı kullanması ve kodun nereye yazılacağının net olması inanılmaz bir disiplin ve rahatlık sağlıyor.

Siz projelerinizde nasıl bir yapı kullanıyorsunuz? Katmanlı mimari sizin için de vazgeçilmez mi yoksa daha farklı, daha hafif pattern'ler mi tercih ediyorsunuz? Laravel'de Eloquent ile Repository pattern kullanmak gereksiz mi sizce? Yorumlarda tartışalım!
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri