Mehmet

WFN Üye
Konular
1,851
Mesajlar
1,852
Çözüm
0
Ticaret Puanı
0
Üyelik
1 Ay 7 Gün
Konum
YurtDışı
Web Sitesi
Var
Alanı
Google Adsense
1/1
Konu sahibi
Bağımlılık enjeksiyonu, bir sınıfın ihtiyaç duyduğu nesneleri kendi içinde oluşturmak yerine dışarıdan almasını sağlar. Böylece sınıflar somut uygulamalara sıkı biçimde bağlanmaz; kodu değiştirmek, test etmek ve farklı ortamlara uyarlamak kolaylaşır. Temel yararı bağımlılığı açık ve değiştirilebilir kılmaktır. Enjeksiyon tek başına her somut bağımlılığı ortadan kaldırmaz; somut sınıf da dışarıdan enjekte edilebilir. Arayüz kullanmak, değiştirilecek uygulamalar arasında ayrıca bir sözleşme sağlar.

Örneğin bir sipariş sınıfı doğrudan new MySqlOrderRepository() kullanıyorsa veritabanı seçimi sınıfın içine gömülür. Bu sınıfı bellek içi bir depo, farklı bir veritabanı veya test amacıyla sahte bir nesneyle çalıştırmak zorlaşır. Bağımlılık enjeksiyonunda sınıf, belirli bir sınıfı değil ihtiyaç duyduğu davranışı tanımlar ve bu davranışı dışarıdan alır.

Somut PHP örneği​


Örnek kurucu özellik yükseltmesi kullandığı için PHP 8 veya sonrası içindir. amount yalnız deneme için tamsayı en küçük para birimi gibi düşünülebilir; hiçbir tahsilat yapılmaz. Aşağıdaki örnekte CheckoutService ödeme işlemini doğrudan yapan bir sınıfa bağlı değildir. PaymentGateway arayüzünü uygulayan herhangi bir nesne dışarıdan verilebilir.

Kod:
<?php

interface PaymentGateway
{
    public function charge(int $amount): bool;
}

final class DemoPaymentGateway implements PaymentGateway
{
    public function charge(int $amount): bool
    {
        return $amount > 0;
    }
}

final class CheckoutService
{
    public function __construct(
        private PaymentGateway $paymentGateway
    ) {
    }

    public function complete(int $amount): string
    {
        if (!$this->paymentGateway->charge($amount)) {
            return 'Ödeme başarısız';
        }

        return 'Sipariş tamamlandı';
    }
}

$gateway = new DemoPaymentGateway();
$checkout = new CheckoutService($gateway);

echo $checkout->complete(100) . PHP_EOL;

Bu dosya çalıştırıldığında beklenen çıktı Sipariş tamamlandı olur. CheckoutService içinde new DemoPaymentGateway() bulunmadığı için ödeme sağlayıcısını değiştirme kararı bu sınıfa yayılmaz. Örneğin gerçek uygulamada farklı bir PaymentGateway sınıfı hazırlanıp kurucuya verilebilir.

Kodda arayüzün yöntem imzasıyla verilen nesnenin uyumlu olması önkoşuldur. Farklı bir sınıf PaymentGateway uygulamıyorsa PHP tür hatası verir; bu, bağımlılığın sözleşmeye uymadığını gösterir. Bu örnek gerçek bir ödeme servisine bağlanmaz; yalnızca bağımlılığın dışarıdan aktarılma mekanizmasını gösterir.

Hangi sorunu ne ölçüde çözer?​


Bağımlılık enjeksiyonu her tasarım sorununu kendiliğinden çözmez. Kazancı, bağımlılıkların nerede oluşturulduğunu ve hangi sözleşmeye göre kullanılacağını ayırmasından gelir.

DurumDoğrudan oluşturmaBağımlılık enjeksiyonu
DeğiştirmeSınıf içindeki new çağrıları düzenlenirDışarıda başka uygulama verilir
TestGerçek altyapı gerekebilirSahte veya bellek içi nesne verilebilir
Bağımlılıkların görünürlüğüKodun içinde gizlidirKurucuda açıkça görülür

Bu nedenle özellikle veritabanı deposu, HTTP istemcisi, dosya sistemi, saat sağlayıcısı veya dış servis istemcisi gibi değişebilen bileşenleri enjekte etmek anlamlıdır. Küçük ve değişmeyecek bir değer için gereksiz arayüzler oluşturmak ise tasarımı karmaşıklaştırabilir.

Uygulama adımları​


  1. Sınıfın doğrudan oluşturduğu ve değişmesi muhtemel nesneleri belirleyin. Örneğin new PDO(...) veya belirli bir API istemcisi bir adaydır.
  2. Sınıfın gerçekten kullandığı davranışları küçük bir arayüzde tanımlayın. Arayüzü, somut sınıfın bütün özelliklerini değil tüketen sınıfın ihtiyacını kapsayacak şekilde tasarlayın.
  3. Somut uygulamayı arayüzü uygulayacak biçimde yazın ve bağımlılığı kurucuda tür belirterek alın. Kurucu enjeksiyonu, nesnenin geçerli bir bağımlılık olmadan oluşturulmasını engeller.
  4. Nesneleri uygulamanın giriş noktasında oluşturup birbirine bağlayın. Bu bağlantı koduna genellikle composition root denir; iş sınıflarına new serpiştirmekten kaçının.
  5. Testte aynı arayüzü uygulayan sahte bir nesne verin. Testin amacı dış servisin çalıştığını değil, tüketen sınıfın doğru kararı verdiğini denetlemekse gerçek servisi çağırmayın.

Enjeksiyonu bir konteyner nesnesini her iş sınıfına verip içeriden keyfi servis aramakla karıştırmayın. Bu service-locator yaklaşımı gerçek bağımlılıkları kurucuda görünmez kılar; sınıfa ihtiyacı olan belirli nesneyi vermek çoğu durumda daha açıktır.

Sık yapılan hatalar​


En yaygın hata, arayüz tanımlayıp sınıfın içinde yine somut uygulamayı oluşturmaktır. Örneğin kurucudan PaymentGateway almak yerine new DemoPaymentGateway() çağırmak enjeksiyonu fiilen ortadan kaldırır.

Zorunlu bir bağımlılığı sonradan atanacak boş bir özellik olarak bırakmak nesneyi geçersiz durumda kullanmaya yol açabilir. Setter enjeksiyonu bütünüyle yanlış değildir; gerekli olma koşulu ve nesnenin yaşam döngüsü açık olmalıdır. Zorunlu bağımlılıkları kurucuda almak, nesnenin oluşturulduğu anda geçerli olmasını sağlar. İsteğe bağlı bağımlılıklar için varsayılan değer veya ayrı bir yapı kullanılabilir.

Son olarak her sınıf için otomatik olarak arayüz üretmek gerekmez. Değişmesi beklenmeyen basit bir değer nesnesini veya saf bir yardımcı sınıfı yalnızca enjeksiyon kullanmış olmak için soyutlamak, okunabilirliği azaltır. Ölçüt, bağımlılığın değiştirilebilir, dış sisteme bağlı veya testte ayrıştırılması gereken bir davranış olup olmadığıdır.

Kaynaklar​



Sık sorulan sorular​


Bağımlılık enjeksiyonu yalnızca kurucu ile mi yapılır?​


Hayır. Kurucu enjeksiyonu zorunlu bağımlılıklar için en güvenli seçenektir; setter veya yöntem enjeksiyonu isteğe bağlı ya da yalnızca belirli bir işlem sırasında gereken bağımlılıklarda kullanılabilir. Seçim, nesnenin geçerli kalma koşullarına göre yapılmalıdır.

Bağımlılık enjeksiyonu ile bağımlılık yönetim konteyneri aynı şey midir?​


Hayır. Enjeksiyon, bağımlılığın dışarıdan verilmesi tekniğidir. Konteyner ise bu nesneleri oluşturup birbirine bağlayan yardımcı bir altyapıdır. Küçük bir PHP uygulamasında bağlantıları elle kurmak da bağımlılık enjeksiyonudur.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Konuyu görüntüleyenler

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic