1 dk

Bağımlılık Enjeksiyonu Test Edilebilirlik ve Modülerliği Nasıl Arttırır

Bağımlılık enjeksiyonunun kodu nasıl daha kolay test edilebilir, yeniden düzenlenebilir ve genişletilebilir hale getirdiğini öğrenin. Pratik desenler, örnekler ve sık yapılan hatalardan kaçınma yollarını keşfedin.

Bağımlılık Enjeksiyonu Test Edilebilirlik ve Modülerliği Nasıl Arttırır

Bağımlılık Enjeksiyonu Ne Anlama Gelir (Jargonsuz)

Bağımlılık Enjeksiyonu (DI) basit bir fikir: bir kod parçası ihtiyaç duyduğu şeyleri kendi yaratmak yerine, onlara dışarıdan verilir.

Bu “ihtiyaç duyulan şeyler” onun bağımlılıklarıdır—örneğin bir veritabanı bağlantısı, bir ödeme servisi, bir saat, bir logger veya bir e-posta gönderici. Kodunuz bu bağımlılıkları kendisi oluşturuyorsa, sessizce nasıl çalıştıklarını da sabitlemiş olur.

Gerçek dünya benzetmesi

Bir ofisteki kahve makinesini düşünün. Makine suya, kahve çekirdeğine ve elektriğe bağımlıdır.

  • Eğer makine sadece kendi aldığı tek bir özel su kartuşuyla çalışacak şekilde tasarlanmışsa, o tedarikçiyle sınırlı kalırsınız.
  • Eğer makine herhangi bir standart su girişini kabul ediyorsa, su kaynağını değiştirmek makineyi değiştirmeden yapılabilir—musluk, filtrelenmiş veya şişe su fark etmez.

DI, ikinci yaklaşıma benzer: “kahve makinesi” (sınıfınız/fonksiyonunuz) işine (kahve yapmak) odaklanır; “malzemeler” (bağımlılıklar) kurulum yapan tarafından sağlanır.

DI ne değildir

DI, belirli bir framework kullanma zorunluluğu değildir ve bir DI konteyneriyle aynı şey değildir. Bağımlılıkları parametreler (veya constructor) aracılığıyla elle geçirerek DI yapabilirsiniz.

DI ayrıca “mocklama” değildir. Mocklama, testlerde DI kullanmanın bir yolu olabilir; ama DI kendisi yalnızca bağımlılıkların nerede yaratılacağına dair bir tasarım tercihidir.

Neden test edilebilirlik ve modülerlik birlikte iyileşir

Bağımlılıklar dışardan sağlandığında, kodunuz farklı bağlamlarda (üretim, birim testleri, demolar, gelecekteki özellikler) çalıştırması daha kolay olur.

Aynı esneklik modülleri daha temiz yapar: parçalar tüm sistemi yeniden kablolamadan değiştirilebilir. Sonuç olarak testler daha hızlı ve daha net olur (çünkü basit yedeklerle değiştirebilirsiniz) ve kod tabanı daha kolay değiştirilebilir (çünkü parçalar daha az iç içe geçmiştir).

Temel Problem: Sıkı Bağlılık Değişikliği Zora Sokar

Sıkı bağlılık, bir kod parçasının diğer parçaların hangisini kullanacağını doğrudan belirlemesiyle oluşur. En yaygın biçim basittir: iş mantığının içinde new çağrısı.

Doğrudan örnekleme gizli bağlılık yaratır

Kasada new StripeClient() ve new SmtpEmailSender() gibi çağrılar yapan bir checkout fonksiyonunu düşünün. İlk bakışta kullanışlıdır—ihtiyacınız olan her şey oradadır. Ama aynı zamanda checkout akışını bu belirli implementasyonlara, yapılandırma detaylarına ve hatta oluşturma kurallarına (API anahtarları, zaman aşımı, ağ davranışı) kilitler.

Bu bağlılık “gizlidir” çünkü yöntem imzasından belli olmaz. Fonksiyon sadece bir siparişi işliyor gibi görünür, ama gizlice ödeme sağlayıcılarına, e-posta sağlayıcılarına ve belki bir veritabanı bağlantısına bağımlıdır.

Değiştirmesi zor bağımlılıklar değişiklikleri yavaşlatır

Bağımlılıklar sabit kodlandığında, küçük değişiklikler bile dalga dalga yayılır:

  • Sağlayıcı değiştirmek (Stripe → Adyen) iş mantığını düzenlemeyi gerektirir, bir bileşeni değiştirmeyi değil.
  • Önbellekleme, tekrar deneme veya logging eklemek birçok çağrı yerine concern'leri iletmek zorunda bırakır.
  • Bir kütüphaneyi yükseltmek geniş bir refaktör olabilir çünkü oluşturma noktaları dağınıktır.

Sıkı bağlılık yavaş veya güvenilmez testler olarak görülür

Sabit kodlu bağımlılıklar birim testlerin gerçek iş yapmasına neden olur: ağ çağrıları, dosya I/O, saatler, rastgele ID'ler veya paylaşılan kaynaklar. Testler izole olmadıkları için yavaş ve zamanlamaya, dış hizmetlere veya yürütme sırasına bağlı oldukları için kırılgan olur.

Dikkat sinyalleri

Eğer şu desenleri görüyorsanız, sıkı bağlılık muhtemelen zaten size zaman maliyeti çıkarıyor demektir:

  • Gizli bağımlılık olarak kullanılan global durum
  • Testler arasında sıfırlanması zor single-tonlar
  • Çekirdek mantıkta her yerde new kullanımı
  • Veritabanı, web sunucusu veya gerçek bir API anahtarı olmadan test edilemeyen kod

Bağımlılık Enjeksiyonu, bağımlılıkları açık ve değiştirilebilir hale getirerek bunları ele alır—iş kurallarını her değiştirdiğinizde yeniden yazmadan.

SSS

Bağımlılık enjeksiyonu basitçe nedir?

Dependency Injection (DI), kodunuzun ihtiyaç duyduğu şeyleri (veritabanı, logger, saat, ödeme istemcisi gibi) içerden oluşturmak yerine dışarıdan alması anlamına gelir.

Pratikte bu genellikle bağımlılıkların bir constructor'a veya fonksiyon parametresine geçirilmesi şeklinde olur; böylece bağımlılıklar açık ve değiştirilebilir olur.

DI, Kontrolün Tersine Çevrilmesi (IoC) ile nasıl farklıdır?

Kontrolün Tersine Çevrilmesi (IoC), bir sınıfın ne yaptığıyla ilgilenmesi gerektiği fikridir, iş ortaklarını nasıl elde edeceğiyle değil.

DI, bağımlılık yaratımını dışarıya taşıyarak IoC'yi sağlamanın yaygın bir yoludur.

İş mantığı içinde `new` çağırmak neden sıkı bağlılığa yol açar?

Eğer bir bağımlılık iş mantığının içinde new ile oluşturuluyorsa, onu değiştirmek zorlaşır.

Bunun sonuçları:

  • sağlayıcıya kilitlenme (ör. checkout'ta Stripe gömülü kalır)
  • yapılandırma ve oluşturma kurallarının dağılması
  • gerçek I/O (network/DB/dosya/saat) yüzünden daha yavaş ve güvenilmez testler
DI birim testleri nasıl daha hızlı ve daha az kırılgan kılar?

DI, testlerde gerçek dış sistemler yerine test çiftleri enjekte etmenize izin vererek testlerin hızlı ve deterministik kalmasını sağlar.

Yaygın değişimler:

  • gerçek DB yerine fake/işlem içi repository
  • sistem zamanı yerine stublanmış saat
  • gerçek e-posta yerine mocklanmış mailer
DI kullanmak için bir DI konteynerine ihtiyacım var mı?

Bir DI konteyneri isteğe bağlıdır. Küçük/orta ölçekli uygulamalarda manuel DI (bağımlılıkları açıkça geçirmek) ile başlayın:

  • uygulama küçükse
  • nesne grafını elle kurmak kolaysa
  • maksimum açıklık istiyorsanız

Konteyneri, wiring tekrar etmeye başladığında veya yaşam döngüsü yönetimi (singleton/per-request) gerektiğinde düşünün.

Constructor, method ve setter enjeksiyonunu ne zaman kullanmalıyım?

Constructor injection: bağımlılık nesneyi oluşturmak için gerekliyse ve birden fazla metotta kullanılıyorsa tercih edin.

Method/parameter injection: yalnızca tek bir çağrı için gerekiyorsa (istek-scope değeri, tek seferlik strateji).

Setter/property injection: gerçekten geç bağlama gerekiyorsa kullanın; eksikse hızlıca hata vermek için doğrulama ekleyin.

Composition root nedir ve nerede olmalı?

Composition root, uygulamanın birleştirildiği yerdir: implementasyonları oluşturup onları ihtiyaç duyan servislere verdiğiniz yer.

Genellikle uygulama başlatma noktasına yakın tutulur; böylece geri kalan kod tabanı davranışa odaklanır, wiring değil.

Test seam nedir ve nerede oluşturulmalı?

Test seam, davranışın kasıtlı olarak değiştirilebildiği bir noktadır.

Seam için iyi yerler:

  • zaman (Clock.now())
  • I/O (file store, HTTP client)
  • dış servisler (ödeme, e-posta)

DI, testlerde farklı bir implementasyon enjekte etmenize izin vererek seam'ler oluşturur.

Yaygın DI hataları nelerdir ve nasıl kaçınırım?

Yaygın hatalar:

  • Aşırı enjeksiyon: çok sayıda bağımlılığa sahip constructor genellikle sınıfın çok şey yaptığına işarettir — sorumlulukları bölün.
  • Service Locator: container.get() çağrısı bağımlılıkları gizler; parametrelerle açıkça geçirmek daha iyidir.
  • Runtime wiring hataları: eksik kayıtlar veya döngüsel bağımlılıklar — uygulama grafını inşa eden hafif bir test ekleyin.
Mevcut bir kod tabanına DI'yi güvenle nasıl getiririm?

Küçük, tekrarlanabilir bir refaktör ile başlayın:

  1. Bir zor bağımlılık seçin (DB, saat, HTTP client).
  2. İhtiyacınız olan davranışı tanımlayan küçük bir arayüz/kontrat çıkarın.
  3. Mevcut somut implementasyonu bu arayüzün arkasına sarın.
  4. Constructor veya parametre yoluyla enjeksiyon yapın.
  5. Üretim wiring'ini composition root'ta güncelleyin.
  6. Testleri fake/stub/mock ile güncelleyin.

Her adımı ayrı ayrı uygulayarak devam edin; istediğiniz noktada durabilirsiniz.

Related posts