Dependency İnjection Nedir? Php Örnek Kullanım

Yazılım geliştirme sürecinde en önemli konulardan biri şüphesiz yazılımın iyi tasarlanmış olmasıdır. Bu projenin geliştirilmesi yönetilmesi ve devamlılığı için çok önemlidir. Proje büyümeye başladıkça yeni ihtiyaçlar, yeni geliştirmeler, ekstra özellikler kazanarak devleşmeye başlar.

Büyük şirketler dahil çoğunlukla önce projenin hayata geçirilmesini isterler; şimdilik bu şekilde yapalım ilk versiyonu çıkartalım biraz ilerleyelim, ileride bunları raylara oturturuz gibi düşünceler yer almaktadır. Ancak iyi hazırlanmamış bir zemine sürekli yeni şeyler inşa etmek sallantılı bir süreç getirir. İlk zamanlarda problem yaşanmasa da ileride proje geliştikçe büyüdükçe ortaya çıkması kaçınılmaz olabiliyor. Ve ileride ya toparlanma zamanı hiç gelmez yada toparlamaya kalktığınızda işin içinden çıkamaz hale gelinebiliyor. Bazen yeni bir özellik eklemek projeyi yeniden yazmaktan daha zor olabiliyor bu sebeple. Bunların bir çok sebebi olmasına karşın bugün bizim konumuz olan çözüm dependency injection.

Dependency injection: bağımlılıkların dışarıdan enjecte edilmesi anlamına gelir.

Yani nedir; yazılımı oluşturan yapıların birbirleri ile olan bağı en aza indirmek. Buna loosely coupled-Gevşek bağlılık denir.

Dependency İnjection Ne Sağlar

Yazılımı oluşturan yapıların birbirleri ile olan sıkı bağ azaldığı için, uygulamaya yeni özellikler eklenip çıkartılabilmesi kolay hale gelir.

Uygulama içerisinde değiştirilmesi müdahale edilmesi gereken yerler minumuma iner.

Test edilebilir yapılar ortaya çıkar.

Özellikler bir yerde

Örnek Seneryolar

Bir çok örnek durum gösterilebilir şuan aklıma gelen bir kaç tanesini paylaşmak istedim. Örneğin birden çok ödeme sistemi var, ileride bunlardan bir tanesini daha projenize dahil edeceksiniz. Müşteriniz bugün mail yoluyla çalışan bildirim sistemini  yarın sms olarak kullanmak istiyor. Bugün a sistemine göre uygulamanızı tasarladınız yarın yeni versiyon veya b ye geçilmek istendi, bugün google dan verileri alıyorsunuz yarın bir müşteriniz yandex tercih edebilir. Yeni bir özellik eklenti geliştirdiniz test etmek istiyorsuuz. Gibi durumlar çoğalabilir.

Uygulamanızı bugün x şirketinin talepleri doğrultusunda google dan verileri alıyor şekilde tasarladınız. Yarın başka bir kurum – müşteri ile daha anlaştınız. Ama bu müşteri benim yandex ile anlaşmam var verileri oradan almamız gerekiyor dedi. Tamam dediniz iyi kötü if ler havada uçuşarak entegre ettiniz. Yarın müşteri dedi ki bizim anlaşmamız bitti artık yahoo ile çalışıyoruz. Ne oldu tekrar baştan aşağı uygulamayı ele alıp kodlarda bir çok değişiklik gerçekleştireceksiniz. Sonra başka müşteri tekrar google verileri ile çalışmak istedi. Ne ya yapacaksınız, tamam bunu daha önce yapmıştık der değişikliğe gidersiniz.

Fonksiyonel veya oop yaptınız. Güzel. Diğerlerini o yüzden commentleyip geçerim

google(); // sen calis

// yandex(); // sen calisma iptal

// yahoo(); // sen calisma iptal

Böyle durumlarda her yeni özellik eklenmek değiştirilmek istendiğinde uygulamanın kodları açılır ve her ilgili methodu,sınıfı içeren yerlerde tek tek değişiklik gerçekleştirilir veya commentlenir. Proje tekrar derlenir veya hazırlanır teslim edilir. Her yeni özellik veya geliştirmede bu işlemler tekrarlanır. Bu istenen bir durum değildir. Zaman ve yoğun emek gerektirebiliyor.

Oysa birbirinden bağımsız şekilde tasarlanan class yapılar ile bunu gerçekleştirmek çok daha kolay ve modülerdir. Burada önemli olan yazılımı oluşturan her bir yapının sadece kendisine ait işlemleri gerçekleştiriyor olması ve diğer bileşenlerle ilgilenmemesi yani bağımlı olmamasıdır. Her bir yeni geliştirme veya özellikte ona ait bir yapı(class) oluşturulur. Çalışma esnasında ise seçime bağlı olarak ilgili özelliğe ait olan yapı uygulamaya dahil edilir ve kullanılır.

Yani config de bakılır google mı yandex mi yahoo mu ne kullanılıyor ise ona ait class uygulamada ilgili yerlere enjecte edilir. Böylece enjekte edilen class lar gelen google mı, yandex mi yahoo mu bilmeden hangisi gelirse gelsin ilgili methodu (örneğin getData) işler.

En Basit Anlamıyla Dependency Örneği

Örneğin bir user class ımız var. Burada kullanıcı ile ilgili işlemler yapıyoruz. Ekle, sil, detay vs. Ve bu işlemler için log tutmak istiyoruz. Hemen user class ımız içinde log class ı ile bağlantı kurarız dimi ?

Örnek:

Class User
{
 public function add()
 {
 ...
 // iste burada Log class ına cok bagimli olduk
 $log = new Log();
 $log->add($userData);
 }
}

İşte user sınıfımızda log class ına bağlı kaldık. Burada Log sınıfı olmazsa User sınıfı çalışamıyor yani log sınıfına bağlı. Bu bağlılığı nasıl azaltabiliriz.

Class User
{
 public Log;
 
 public function __construct($log)
 {
 $this->Log = $log;
 }
 
 public function add()
 {
 ...
 // artık log disaridan enjecte ediliyor, bagimlilik azaldi
 $this->Log->add($userData);
 }
}

$log = new Log();
// user class ına disaridan enjekte ediyoruz
$user = new User($log);

Görüldüğü üzere User class ı başlamadan önce oluşturulan log classı user class ına dışarıdan veriliyor. Böylece user sınıfı log sınıfını bilmek zorunda değil. LogSms, logMail,logFile gibi yeni class lar da oluşturulup verilebilir. Ama user sınıfı hep aynı işlemi yapar, gelen log sınıfının türünü bilmez sadece add methodunu çağırır. Yani tek config de işi bitiriyor oluyoruz.  Oysa biz dependency injection kullanmasaydık ve log sınıfını bir müşterimize göre sms olarak çalıştırmak iseteseydik, log sınıfını kullanan tüm sınıflarda tek tek bulup yerine new LogSms() yazacaktık.

Umarım giriş anlamında bir şeyler şekillenmiştir. Şuan karmaşık gelebilir örneğimizde detaylı uygulamalı göreceğiz

Php ile Dependency İnjection Örnek Uygulama