Dependency Inversion Principle — SOLID
Herkese medium’daki ilk yazımdan merhabalar!
Bu yazımda benim öğrenirken en çok zorlandığım SOLID prensibi olan Dependency Inversion’ın ne olduğunu anlatmaya çalışacağım. Ama öncesinde sondan başlamamak adına SOLID nedir? Ne için kullanılır ? Ne işe yarar? diğer prensipleri neler? Bunlara değinmek istiyorum.
Acaba mülakatlarda sorarlar mı? Acaba karşıma çıkar mı? diye düşünerek bir çok yazılımla uğraşan kişinin karşısına çıkmıştır SOLID. Asıl amacı yazılımda sürdürebilirliği sağlamak için kullanılan 5 adet prensibin birleşimidir denilebilir. Peki yazılımda sürdürebilirlik ne derseniz; yazılım genel anlamda insanların gündelik işlerini bilgisayar sistemleriyle daha kolay hale getirilmesidir. Fakat yazılım bir bina değildir yani yaptım bitti diyemezsiniz, insanların istekleri ve koşullar doğrultusunda sürekli gelişip, değişebilmeli yani sürdürülebilir olmalıdır. Esnek ve yönetilebilir kod yazmak, kodda okunaklılığı arttırıp karmaşayı azaltmak aslında SOLID’in yaptığı şeydir.
SOLID Prensipleri
SOLID ile ilgili çok fazla bilgilendirici hem Türkçe hem İngilizce kaynak ve makale hali hazırda bulunmakta. Ben asıl konum olan Dependency Inversion’a geçmeden önce ilk 4 prensipten şimdiye dek ne anladıysam özet olarak onu sizlere aktarmak istiyorum.
Single Responsibility:
SOLID’in ilk prensibi olan Single Responsibility Türkçe’ye tek sorumluluk, tek görev olarak çevrilebilir. Bu prensip her sınıfın veya her metodun sadece tek bir sorumluluğu olması gerektiğini ve eğer bir nesne içerisinde değişiklik yapmak için birden fazla sebep gerekiyorsa bu prensibe uymadığımızı savunmaktadır.
Open/Closed Principle:
Ana mantığı sınıflar değişikliğe kapalı fakat gelişime açık olmak olan OCP prensibi, uygulamaların yeni özellik eklemeye açık olması gerektiğini fakat bu değişiklikler mevcut kodları değiştirerek yapılmaması fikrini savunur.
Liskov’s Substitution Principle
Bu prensibin temel amacı ise alt seviyedeki nesnelerin, üst seviyedeki nesneler ile yer değiştirebilir olmasını sağlamaktır. Savunduğu fikir ise alt seviye bir sınıf, üst seviyesi olan sınıf ile aynı şekilde davranmalı ve üst sınıfın tüm özelliklerini kullanabilmelidir.
Interface Segregation
Bu prensip bize der ki tek bir interface yerine kullanımlarına göre parçalanmış birden fazla interface ile işlemleri yürütmeliyiz. Yani her farklı görevin kendine özgü bir arayüzü olması gerekmektedir. Nedeni ise interface’i kullanan kişinin sadece ihtiyacı olanlarla ilgilenebilmesidir.
Dependency Inversion
Asıl bahsetmek istediğim ve SOLID’in son prensibi olan Dependecy Inversion’ı her zaman Dependency Injection ile karıştırmıştım hatta ilk duyduğumda ikisinin aynı şey olduğunu düşünmüştüm. Gerçekten ne olduklarını öğrendiğimde farkettim ki tabiki de ikisi farklı şeyler fakat alakasız şeyler değil.
Öncelikle söyleyebilirim ki SOLID’in son prensibi olan Dependency Inversion problem çözmeye yarayan bir prensip iken Dependency Injection bunu uygulayan bir design pattern’dir. Şimdi ikisini de önce teorik sonra pratikte daha yakından inceleyelim ve ne demek istediğimi anlamaya çalışalım…
Nesne yönelimli programlamada bir nesne oluşturulur ve bu nesne görevini yaparken diğer nesnelerle iletişim halindedir. Bu da haliyle bağımlılıkları oluşturur. Dependency Inversion prensibi ana hatlarıyla şunu savunur alt sınıftaki değişiklikler üst sınıfı etkilememeli ve bağımlılık en aza indirilmeli, minimize edilmelidir.
Dependency inversion prensibinin uygulanmasını içeren bir design pattern olan Dependency Injection ise temel olarak bağımlılıkların kontrolü ve yönetimi için kullanılmaktadır. Dependency injection ile bir sınıfın bağımlı olduğu nesneden bağımsız hareket edebilmesini sağlayabilir ve kod üzerinde olası geliştirmeler için değişiklik yapma ihtimalini ortadan kaldırabilirsiniz aslında böylece OCP prensibine de uyulmuş olunur.
Genel olarak şöyle söyleyebiliriz oluşturacağınız bir sınıf içerisinde başka bir sınıfın nesnesini kullanacaksanız eğer bunu new ile oluşturmamalısınız der Dependency Inversion. Ne yapmamız gerektiğine gelecek olursak da gereken nesnenin ya constructor’dan ya da setter metodu ile parametre olarak alınmasını savunur. Aslında bu da Dependency Injection’dır. Böylece 2 sınıf birbirinden izole edilmiş olur. Şimdi biraz da kod üzerinde daha iyi anlamaya çalışalım =)
Öncelikle çoğumuzun kodu Dependency Inversion prensibine dikkat etmeden nasıl yazdığımıza basit bir örnek vereceğim…
Diyelim bir çeşit çeşit pizzalar yapan bir dükkan var ve biz burdan karışık pizza istiyoruz. Görüldüğü gibi iki classımızı oluşturduk ve bir de Pisir methodumuz var. Ve oluşturacağımız bir sınıf içerisinde başka bir sınıfın nesnesini kullanmak için new kullandık. Yani iki class artık bağımlı oldu.
Eğer başka birisi gelse ve mozerellalı veya başka bir çeşit pizza isterse Pizza classına gelip new’lediğimiz yeri değiştirmemiz gerekecek ve bu da aslında bağımlılığın göstergesidir.
Peki bunu Dependency Inversion prensibine uygun hale nasıl getirip bağımlılığı azaltabiliriz? Tabiki öncelikle bağımlılık dendiğinde bir interface oluşturacağımızı anladık. Pizzamız neyli olursa olsun o classta Pisir methodu içeren IPizza interfacemizi implemente edebiliriz.
Dediğim gibi bir de mozarellalı bir pizza istensin. Classımızı oluşturup implemente ettik.
Görüldüğü gibi artık Main’de işler çok kolay. Hangi pizza istenilirse o gönderilir. Yani aslında bağımlılığı dışardan almış olduk (INJECTION).
Tabiki bu konunun daha iyi anlaşılabilmesi için basit bir örnekti. Fakat daha büyük ve karışık projelerde aslında Dependency Inversion önemi daha da artmaktadır.
Özet
Buraya kadar, bu beş ilkenin ne olduğunu ve SOLID’in temel mantığını anladık. SOLID kodumuzun düzenlenmesini, genişletmeyi ve çok az sorunla veya hiç sorun yaşamadan test etmeyi kolaylaştırmanıza yardımcı olacak ayrıca kodun sürdürülebilir olmasını sağlayacaktır. Dependency Inversion ise büyük sistemlerin hiçbir zaman küçük sistemlere bağımlı olamayacağını vurgular ve bağımlılığı minimize etmemize yardımcı olur diyebiliriz.
Umarım az da olsa daha da iyi anlamanıza yardımcı olabilmişimdir.Okuduğunuz için teşekkürler.
Bir sonraki yazımda görüşmek üzere…