Bağımlılık Enjeksiyonu
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 57 / 91.
Önceki derste, bileşimin bir Car nesnesinin bir Engine nesnesi içermesine nasıl olanak tanıdığını gördün. Ancak sınıfın içinde bağımlılıklar oluşturmakla ilgili bir sorun vardır; bu, kodu katı ve test edilmesi zor hâle getirir. Bağımlılık Enjeksiyonu, bağımlılıkları içeride oluşturmak yerine dışarıdan geçirerek bu sorunu çözer.
Bu iki yaklaşımı karşılaştırın:
<?php
// DI olmadan - bağımlılık içeride oluşturuluyor
class Car {
private Engine $engine;
public function __construct() {
$this->engine = new Engine(); // Sıkı bağlı
}
}
// DI ile - bağımlılık dışarıdan geçiriliyor
class Car {
public function __construct(private Engine $engine) {}
}
$engine = new Engine();
$car = new Car($engine); // Dışarıdan enjekte edildi
İkinci yaklaşım bağımlılık enjeksiyonudur. Car kendi motorunu oluşturmaz - bir motor alır. Bu basit değişikliğin güçlü faydaları vardır: farklı motor türleri geçirebilir, test için uygulamaları değiştirebilir ve sınıf daha esnek hâle gelir.
Daha da fazla esneklik için somut sınıflar yerine arayüzleri enjekte edin:
<?php
interface EngineInterface {
public function start(): string;
}
class Car {
public function __construct(private EngineInterface $engine) {}
public function start(): string {
return $this->engine->start();
}
}
Artık Car, EngineInterface uygulayan herhangi bir class ile çalışır — benzinli bir motor, elektrikli motor veya test için bir mock. Bu gevşek bağlılık, bağımlılık enjeksiyonunun sürdürülebilir ve test edilebilir PHP uygulamaları yazmak için neden temel olduğunu açıklar.
Görev
KolayBağımlılık enjeksiyonunun gücünü gösteren bir bildirim sistemi oluşturalım. Mesajların nasıl gönderileceğini sabit kodlamak yerine, teslim yönteminin kolayca değiştirilebildiği esnek bir sistem oluşturacaksın.
Kodunu dört dosyaya ayıracaksın:
MessageSenderInterface.php:MessageSenderInterfaceadlı, tek birsend(string $recipient, string $message): stringyöntemine sahip bir arayüz tanımla. Bu arayüz, herhangi bir mesaj göndericisinin uyması gereken sözleşmeyi belirler.EmailSender.php:MessageSenderInterfacearayüzünü uygulayan birEmailSendersınıfı oluştur. Arayüz dosyasını dahil et.send()yöntemi"Email to [recipient]: [message]"döndürmelidir.NotificationService.php: Bağımlılığını oluşturucu aracılığıyla alan birNotificationServicesınıfı oluştur. Arayüz dosyasını dahil et. Sınıf şunları yapmalıdır:- Oluşturucu terfisini kullanarak oluşturucusunda bir
MessageSenderInterfacekabul et - Enjekte edilen göndericiye yönlendirme yapan ve sonucunu döndüren
notify(string $recipient, string $message)yöntemine sahip ol
NotificationServicesınıfının somut bir sınıfa değil, arayüze bağlı olduğuna dikkat et. Bu, hizmeti değiştirmeden arayüzü uygulayan herhangi bir göndericiyi enjekte edebileceğin anlamına gelir.- Oluşturucu terfisini kullanarak oluşturucusunda bir
main.php: EmailSender ve NotificationService dosyalarını dahil et. İki girdi alacaksın: bir alıcı ve bir mesaj. BirEmailSenderoluştur, bunu birNotificationServiceiçine enjekte et, ardındannotify()yöntemini çağır ve sonucu yazdır.
Bu desen, NotificationService sınıfını esnek tutar. E-posta, SMS veya henüz oluşturmadığın başka bir şey olması fark etmeksizin, enjekte ettiğin herhangi bir göndericiyle çalışır. Hizmet kendi bağımlılıklarını oluşturmaz; bunları dışarıdan alır.
Kendin dene
<?php
require_once 'EmailSender.php';
require_once 'NotificationService.php';
// Girdiyi oku
$recipient = trim(fgets(STDIN));
$message = trim(fgets(STDIN));
// TODO: Bir EmailSender örneği oluştur
// TODO: Bunu bir NotificationService'e enjekte et
// TODO: notify() metodunu çağır ve sonucu yazdır
?>Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar SözcüğüMetotlarÖzelliklerYapıcı (__construct)Yıkıcı (__destruct)Tekrar - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar SözcüğüMetot Geçersiz Kılmafinal Anahtar SözcüğüSoyut SınıflarTekrar - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicileri DerinlemesineGetter ve Setter'larBilgi GizlemeYapıcı Özellik Terfisi (8.0)Tekrar - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Composition ve KalıtımBağımlılık EnjeksiyonuAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlamaya Derinlemesine BakışÜreteçler ve Yineleyiciler13Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıBileşik KalıpDepo Kalıbı2Namespace’ler ve Autoloading
Namespace’lere Girişuse Anahtar SözcüğüPSR-4 Autoloading StandardıComposer AutoloaderTekrar - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Çok Arayüz UygulamaArayüz ve Soyut Sınıf KarşılaştırmasıArayüzlerle Tür İpuçlarıTekrar - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString ve __debugInfo__get, __set, __isset, __unset__call ve __callStatic__clone ve Nesne Klonlama__serialize ve __unserializeTekrar - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerSalt Okunur Özellikler (PHP 8.1)Tekrar - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmayı Yeniden Ele AlmaArayüzler Yoluyla Çok BiçimlilikTür İpuçları ve Birleşim TürleriGeç Bağlanan Statik ÇağrılarÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişBirden Çok Trait KullanımıTrait Çakışmalarını ÇözümlemeTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım Karşılaştırması12Tasarım Desenleri 1. Bölüm
Tasarım Desenlerine GirişSingleton DeseniFactory DeseniObserver DeseniStrategy DeseniKendi başına pratik yap: Online PHP derleyicisi