Dependency Inejctionlar

Furkan Şahin Kulaksız
4 min readOct 11, 2020

--

Yazıya geçmeden önce gerçek hayattan bir örnek vermek istiyorum. Bir arsaya bina yapılırken 3.kata gelindiğinde müteahhitin “ya odaları artık 30m2 değil de 20m2 yapalım” demesi mümkün değildir. Ya da bina artık bitmiş, 10 katlı binanın 10.katı yapılırken, inşaat mühendisinin çıkıp da “Müşteri10 katlı binadan vazgeçti. 2 katını yıkalım.” demesi söz konusu değildir. Ama yazılımda bu yaklaşımlar vardır, doğrudur ve mantıklıdır. Çünkü developer işi yanlış anlamış olabilir. Müşterinin farklı bir ihtiyacı doğabilir ya da mevduat değişebilir. İşte bu gibi durumlarda da yazılım değişime ayak uydurabilecek esneklikte olmalıdır. Bunu sağlamak için ise çeşitli yaklaşımlar, esnek olması için prensipler ya da kalıplar geliştirilmiştir. (Bkz. Design Patternlar — SOLID vs.)

Bizim bugünkü konumuz ise “Dependency injectionlar.” (Bu konuya bakmadan önce Inversion of Control hakkında bilgi sahibi olmanızı öneririm.)Dependency injection aslında bir konsept. Bağımlılıkları yönetmemizi sağlayan bir yapı. Konsept diyorum, çünkü java harici programlama dillerinde de kullanılan / kullanılması gereken bir yaklaşım. “Must” bir yaklaşım değil belki ama “Must’a en yakın should” dersem yanılmış olmam herhalde. Temiz kod yazma, ya da kodu yönetebilme adına bize kolaylıklar sağlar. Bir çoğumuz gözardı ediyoruz, etmeyelim. 😄 En basit sebebi ise proje büyüdükçe kod spagettiye döner. Spagettiye dönen kod ise yönetilmez. Kodun her yerini if blokları kaplar vs. (Not: Dependency injectionları bilmemiz için bir diğer sebep ise mülakat sorusudur.)

Tek tek gidecek olursak;

Dependency -> Bağımlılık,

Injection -> enjekte etme

diyerek direk translate yapabiliriz. Bütünde ise “bağımlılıkları enjekte etmek” diye bir kavram çıktı karşımıza.

Peki buradaki bağımlılıktan (dependency)kastımız ne.?

Terminolojik olarak, “bir sınıfın bir başka sınıfa / sımıfta ya da o sınıfın fonksiyonlarına ihtiyaç duyması / kullanılması” gibisinden bir tanım yapmak yanlış olmaz sanırım.

Burada görüldüğü üzere, Öğrenci sınıfı bir şekilde Okul sınıfının içerisinde kullanılmış. Ya da kullanılmak zorunda. Class sınıfı okul sınıfına bağımlı yani görüldüğü üzere. Ama temiz kod yazma tekniklerine göre, Class sınıfı içerisinde okul sınıfını new lememiz gerekir.

Mesela bir senaryo düşünelim. Hizmet verdiğimiz bir tane müşteri olsun. veritabanını olarak da MsSQL kullanıyor olsun.

Bu şekilde simülasyon yaptığımızı düşünürsek, basit bir DAL katmanı ve bu katmana çeşitli kurallardan geçmiş verileri yollayan Business Logic katmanı. Burada herhangi bir sıkıntı gözükmüyor gibi şimdilik. Ama başka bir müşteri ile anlaştınız diyelim ve o müşteri PostgreSql veritabanı kullanıyor. İşte burada developer, kafasını kaşımaya başlar ve çözüm üretmekte zorlanır. Çözüm üretemediği için de bir type parametresi geçer ve buna göre if — else bloklarıyla işi çözmeye çalışır. Belki de çözer. Ama kod artık spagetti olmuştur. Başka bir müşteri ile anlaşıldığında o da oracle kullanıyordur vs. Yani git gide kodu yönetmek zor hale gelmiştir.

Peki bu durumda ne yapmamız lazım.? Aslında SOLID kavramları bize hangi durumda ne yapmamız gerektiğini söyler ama, bizim burada yapmamız gereken ortak bir interface oluşturmak ve işlemlerimizi onun üzerinden yapmak.

Oluşturduğumuz bu interface’i DAL katmanımız implemente eder ama BusinessLogic class’ında dependency injection kullanımını görüyoruz. Interface tipinde bir field üretilmiş. ve bu field tipinde parametre alan bir constructor üretilmiş. İşte biz işlemlerimizi tamamen bunun üzerinden gerçekleştiriyoruz. (Constructor injection)

İkinci bir yöntem ise Setter Injection.

Bir sınıf başka bir sınıfta kullanılıyorsa dependency olan sınıfı new lememek gerektiğinden ötürü; bu sınıfla alakalı işlemlerimizi set ve get methodlarıyla gerçekleştirmemiz gerekir.

Araştırmamı yaparken bunlar gibi başka dependency injection yöntemleri de gördüm. @Inject annotasyonu ile, interface injection yöntemi ile ya da Spring tarafında @Autowired annotasyonu ile DI kavramının işlendiğini gördüm. (Geçen haftaki yazımda @Autowired annotasyonunu kullanmıştım. Aslında tanım olarak bir bean içerisindeki yapıpyp bozulmadan başka bir bean içerisine taşımamızı sağlıyor diyebiliriz.) Önemli bir konu dependency injectionlar. Üzerine onlarca makale yazılmış bir konu. Önemli olmasının sebebi, her geçen gün parabolik bir artışla gelişen yazılım dünyasında ihtiyaçlara cevap verirken development tarafında da sistematik bir şekilde gitmeyi amaçlaması. Kodu yönetmeyi sağlaması. Bu konu özellikle Inversion of Control ile ya da SOLID kavramlarının sonuncusu olan Dependency Inversion ile doğrudan alakalı bir konu. Bu konulara da bir gözatmanızı tavsiye ederim.

Eğer yanlış ya da eksik gördüğünüz yerler varsa lütfen bana bildiriniz. Yapıcı eleştrilere her zaman açığım. 😊

Ben Furkan Şahin KULAKSIZ

Java İle Kalın. (:

İletişim, İşbirlikleri ve Teklifler için

github: https://github.com/frknshnklksz

twitter: https://twitter.com/frknshnklksz

gmail: furkansahinkulaksiz@gmail.com

linkedIn: https://www.linkedin.com/in/frknshnklksz/

--

--