Ocak 16, 2022 · 2 dakikaBağımlılık Yönetimi - Dependency Injection
Selamlar 🙋🏻♂️ Bizler çoğu zaman gerçek hayat problemlerini kodumuzda simulate ediyoruz. Geliştirme yaparken yani sınıflarımızı oluştururken pek çok sınıf içerisinde başka bir sınıf çağrısı kullanmak zorunda kalıyoruz. Bu gereksinim aynı zamanda bağımlılık olarak isimlendiriliyor. Aşağıda bir örneğini senin için paylaştım. Daha iyi kavramana yardımcı olacaktır.
Bir arama kutusu için yazım denetleyicisine ( SpellChecker ) ihtiyacımız olsun. Kullanıcı bir şeyler arattığında yazdığı metnin doğruluğunu kontrol edeceğiz veya öneri sunacağız. Kontrol ederken de elimizde ki bir sözcüğe bakacağız (Lexicon).
// Inappropriate use of static utility - inflexible & untestable!
public class SpellChecker {
private final Lexicon dictionary = ...;
private SpellChecker() {} // Noninstantiable
public boolean isValid(String word) { ... }
public List < String > suggestions(String typo) { ... }
}
Oluşturduğumuz yazım denetleyiciyi daha önceki yazılardan birinde incelediğimiz gibi singleton class olacak şekilde de oluşturabiliriz. Şöyle ki;
// Inappropriate use of singleton - inflexible & untestable!
public class SpellChecker {
private static final Lexicon dictionary = ...;
private SpellChecker(...) {}
public static SpellChecker INSTANCE = new SpellChecker(...);
public boolean isValid(String word) { ... }
public List < String > suggestions(String typo) { ... }
}
Çok güzel! Yazım denetleyicimiz kullanıcının yazmış olduğu girdiyi alıp sözlüğümüz içerisindeki bilgilerle eşleştirip doğrulamakta. Peki ya dil değiştiğinde ne olacak? Peki test etmek için bir sözlük girmek istediğimizde ne yapacağız? Yazdığımız class'ı test edemeyecek miyiz? Her dil ve testleri için farklı farklı SpellChecker'lar mı yazacağız? Tabii ki hayır!
Sınıfımızın içerisindeki bağımlılıklarımızı çözmemizin en iyi yolu bu bağımlılıkların sınıfımızın içerisinde değil, dışarıdan dahil edilmesi olacaktır. Bir enjeksiyon edasıyla sınıfımızın içerisine bağımlılıklarımızı dahil etmeliyiz. Bu işleme Dependency Injection ismi veriliyor.
Tüm bu bilgiler ışığında örneğimizdeki bağımlılık ise sözlüğümüz olan Lexicon. Kodu tekrardan ele aldığımda aşağıdaki şekilde sözlüğün tanımını sınıfımızın içerisinde yazmayıp dışarıdan constructor ile almamız gerekiyor.
// Dependency injection provides flexibility and testability
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = Objects.requireNonNull(dictionary);
}
public boolean isValid(String word) { ... }
public List < String > suggestions(String typo) { ... }
}
Gördüğünüz gibi artık istediğimiz sözlük ile yazdığımız yazım denetleyicimizi kullanabilir ve test edebiliriz.
Özet
Davranışı sınıfı etkileyen bir veya daha fazla bağımlılığı uygulamak için singleton veya statik utility sınıf kullanmayın ve sınıfın bu kaynakları doğrudan oluşturmasına izin vermeyin. Bunun yerine Dependency Injection kullanarak bir sınıfın esnekliğini, yeniden kullanılabilirliğini ve test edilebilirliğini büyük ölçüde arttırın.
