Android Dependency Injection-Koin
Selamlar sevgili dostlar, bugün sizlere Dependency Injection(DI) hakkında örnekler üzerinden bilgi vermeye çalışıp daha sonrasında Koin ile ufak bir çalışma yapacağız. Hadi başlayalım.
Dependency Injection’a geçmeden önce ufak bir SOLID’i ifade edelim. Çünkü DI aslında SOLID’in “D” açılımı olan Dependecy Inversion içerisinde, bağımlılıkları ortadan kaldırma işlemini Dependency Injection denilen teknik ile gerçekleştiriyoruz.
SOLID
Nesne odaklı bilgisayar programlamada SOLID, yazılım tasarımlarını daha anlaşılır, esnek ve sürdürülebilir hale getirmeyi amaçlayan beş tasarım ilkesinin anımsatıcı bir kısaltmasıdır. İlkeler, Amerikalı yazılım mühendisi ve eğitmen Robert C. Martin tarafından desteklenen birçok ilkenin bir alt kümesidir.
SOLID tasarım ilkelerinin anlaşılması ve uygulanmasını oturtmak biraz zaman alabilir. O yüzden özümseyerek anlamaya gayret ediniz.
Dependecy Injection Nedir?
Özünde bizlerin proje geliştirirken bağımlılıkları en aza indirgememizi farklı sınıflardan oluşturulan instance’ları ortadan kaldırmamıza olanak tanıyor. Peki bu ne anlama geliyor hadi biraz daha açalım.
Şöyle ki, bir proje geliştirirken birden fazla class ile çalışırız. Her bir class farklı amaçlara hizmet eder ve birbirleri içerisinde bu class’ların objelerini türetiriz. Bu sayede farklı class’ta ki metotlara ve değişkenlere ulaşıp, işlemlerimizi gerçekleştiririz.
Dependency Injection da bize şöyle der, kardeşim iyi hoş class’lar dan objeler türetiyorsun da, yarın bir gün bu yapı üzerinde çeşitli değişiklikler yapmanı istediklerinde kullandığın class’lar ve oluşturduğun instance’lar üzerinde tek tek mi değişiklik yapacaksın? Gel sen bağımlılıklarını en aza indir, böylelikle projede daha rahat geliştirme yapabilirsin. Çünkü diğer yandan yaptığın değişikliklere bağımlı olan yavrucuklar olduğu için onları da bu değişikliğe uyarlaman gerekecek. Bu işlem de bir hayli zor ve karışık olacağı için bağımlı etme kendine.:)
Bina Örneği
Kendi açımdan, olayın neye çözüm sunduğunu anlamak kodun yazılmasından daha önemlidir diye düşünüyorum. Çünkü çeşitli syntax’ları kullanıp bunları ezberlemek falan zorunda değiliz. Ama DI hangi problemden meydana çıkmış? Bizleri ne gibi bir çözüme kavuşturuyor? Bu soruların cevaplarını verdiğimiz zaman syntax’ı yazmak daha anlaşılır ve kolay olacaktır.
Bir müteahhit inşa ettiği binanın 3.Katının 200 m2 den, 100m2 ye küçültülmesini veya 3.kata aynı m2 de bir daire inşa etmek istemesi pek mantıklı olmayacaktır. Çünkü 5 katlı inşa edilmiş bir binada böyle köklü bir değişiklik yapmak pek mantıklı değildir ve kimse böyle bir talepte bulunmaz.
Yazılım tarafında da insanların istekleri, bir dairenin m2 sini küçültmek veya farklı bir daireyi inşa etmek gibi mantıksız gelebilir. Fakat yazılım özünde insanların problemlerine bilgisayar destekli sistemler ile çözüm sunduğuna göre. İnsan problemleri gün geçtikçe evirilmekte ve değişiklik göstermektedir.
Bu da demek oluyor ki yarın öbür gün yazılan bir proje üzerinde 3.Kat gibi köklü bir değişiklik veya ekstra bir daire entegre etmek gibi değişiklikler gerekebilir. Bizler de bu değişikliklere hazır ve nazır olmalıyız.
Android tarafında DI için Koin, Kodein, Dagger2, Hilt, Manuel DI gibi farklı yapıları tercih edebilirsiniz. Hepsinin kendilerine göre avantajları ve dezavantajları mevcuttur.
Koin
Koin, Dependency Injection freamworklerinden birisidir. Kotlin programla dili ile geliştirilmiştir. Genelde ufak ve orta çaplı projelerde tercih edilir.
Yapacağımız ufak proje namaz vakitlerini günlere göre listeleyen bir app olacak. Hadi başlayalım.
Build.gradle(app)
//Koin
def koinVersion = '2.1.6'
implementation "org.koin:koin-androidx-viewmodel:$koinVersion"
Modül
Bağımlılıklarımızı oluşturacağımız bir modül yazacağız. Activity, Fragment ve ViewModule için tek bir modül oluşturabilirsiniz. Biz uygulamamız için 3 adet modül oluşturacağız appModule, networkModule, roomModule.
AppModule, içerisinde repository ve viewModel tanımlamalarını yapıyoruz.
NetworkModule, içerisinde Retrofit tanımlamalarını ifade ediyoruz.
RoomModule, içerisinde Room tanımlamalarını yapıyoruz.
get() : Class’ın constructor’ındaki değerleri enjekte etmek için kullanılır.
single : Tekli tanımlama yaparken kullanılır. Her çağırımda yeni örnek oluşturmaz.
factory : Her çağırıldığında yeni bir örnek oluşturacak şekilde tanımlama yapılır.
Application
Artık modüllerimizi oluşturduğumuza göre, Application’dan extend alan bir class oluşturup startKoin bileşeni ile modüllerimizi tanımlayabiliriz. Ayrıca oluşturduğumuz class’ı Manifest.xml içerisinde belirtmemiz gerekmektedir.
name = Bu bileşen, farklı sınıflarda aynı sınıfın birden fazla örneğine sahip olmak istediğinizde gereklidir.
HomeFragment
Son olarak UI içerisinde kullanacağımız ViewModel’ın inject işlemlerini gerçekleştiriyoruz.
Gelin neler yaptık hep birlikte bir özet geçelim. Normalde kullanacağımız classların instance’larını farklı classlarda tanımlıyorduk. Bunun yerine modüller içerisinde bu işlemleri tanımladık. Ardından Network ve Room işlemleri için birer modül yazdık. Tüm bu modülleri bir Application içerisinde başlattık ve son olarak ViewModel içerisinde inject işlemini gerçekleştirdik.
Kod akışının geri kalan kısımlarına yazının sonunda bırakacağım github linkinden ulaşıp detaylı bir şekilde inceleyebilirsiniz.
Yaptığımız işlemleri daha iyi anlamak açısından bir kaç değişikliği BeforeDI — AfterDI şeklinde görsellendirelim.
DI kullanmayı ufak çaplı projelerde tercih etmeniz önerilmiyor. 4 –7 view bir app için çok mantıklı olmayacaktır. Daha çok kod karmaşası oluşacağı büyük çaplı projelerde kullanılması tercih ediliyor.
SOLID programlama biraz ileri seviye olduğu için özümsemesi de zor olabiliyor. DI da bu yapının içerisinde olduğundan dolayı çeşitli kafa karışıklıkları oluşabilir. Bu yönde bir çekinceniz oluşmasın araştırdıkça ve elinizi kirlettikçe kullanmaya başlayabilirsiniz.
Evet sevgili dostlar DI-Koin’i konu edindiğim yazımın sonuna geldik. Umarım sizlere faydalı bilgi aktarımında bulunabilmişimdir. Keyifli Günler, Keyifli Kodlamalar.
İletişim; Linkedin
Kaynaklar