Merhabalar, 9 yıldır yazılım sektöründen kazandığım tecrübeleri tekrar sektöre kazandırmam gerektirdiğine inanıyorum. Ülkemizde ki ekosisteme bir şeyler kazandırmak ilerlememiz için hepimizin görevi aslında. Bende ilk yazımı paylaşmaktan mutluluk duyuyorum, faydalı olması dileğiyle.
Teknik borç (technical debt) uygulamamız içerinde yer alan gözle görünebilen, bir işi yaparken kullanılan nesne, bileşen, bağımlılık ve bazı desenlerin gereğinden eksik yada fazla kullanılması sonucunda ortaya çıkan bakım maliyetlerinin dışa vurumudur aslında. Bu borç verimsiz çıktıya, motivasyon düşüklüğüne, yeni geliştirmelerin uygulanmasına, bir şeyleri iyileştirmeye ve en önemlisi önceki yazılımcının kulaklarının çınlamasına 🙂 sebep olur. Bu yazıda sizlere teknik borcun belkide en önemli maddelerinden bir olan bağımlılıkların yönetilmesi konusunda bir şeyler anlatmaya çalışacağım.
Yazılım geliştirdikçe karmaşıklaşan nesnelerin, bileşenlerin ve modüllerin bir birilerine olan bağımlılığının (coupling) arttığı bir şeydir. Bir nesnenin bazı iş süreçlerini sürdürmesi için başka bir nesneye olan ihtiyacı bağımlılığı doğrurur. Yazılımda gevşek bağımlılık (losely coupled) sürdürülebilirlik açısından önemlidir. Aksi takdirde sıkı bağlı (thight coupled) yazılımda yeni özellik eklemek, iyileştirme ve bakım çalışmaları çok zahmetli olur ve bir süre sonra bu uygulamayı yeniden yazalım fikiri doğar. Sıkı bağlılığı yüksek uygulamalarda genelde teknik borç fazladır. Çünkü zamanında yapılmayan yeniden düzenleme (refactoring), katlanarak büyümüş ve artık değiştirilemez koda sahip olunmuştur.
1960 yılında coupling ve cohesion Larry Constantine tarafından Structured Design parçası olarak yazılım kalite metrikleri kapsamına alınmıştır. – Wikipedia
İş ihtiyaçlarına yazılım ile çözüm üretirken sürdürülebilirliği (maintainability) göz önünde bulundurmalıyız. Yani günümüzde yazılmış olan bir uygulamanın yıllar sonra bile yeni bir özellik eklerken, var olanları değiştirirken yada bir şeyleri iyileştirirken bile çalışabilirliğinden ödün vermemeli. Evet, bunu yapmak mümkün. Aşağıda belirtilen prensipleri gözeterek yazılan uygulamalarda çok rahat hareket edebilirsiniz. Ayrıca Java dünyasınca çok güzel belgelenmiş şu sayfayı incelemenizi öneririm. Ben bu yazıda Dependency Injection hakkında bilgi vermeye çalışacağım.
- Separation of concerns
- Encapsulation
- SOLID
- Don’t repeat yourself (DRY)
- Persistence ignorance
- Bounded Context ve daha bir çoğu
Inversion of Control – IoC
Bağımlılıkların tersine çevrilmesi; ihtiyacı olan nesneye ihtiyaç duyduğu hizmeti oluşturmasına izin vermek yerine hizmeti istemciye dışarıdan vermek modelin temel gereksinimidir. Don’t call us, we’ll call you yöntemi ile çalışır. IoC yapabilmek için Factory Pattern, Service Locator Pattern, Dependency Injection, Contextualized Lookup, Template Method Pattern, Strategy Pattern kullanılabilir.
Inversion of Control Faydaları;
- Programın modülerliğini arttırmak ve genişletilebilir hale getirmek
- Bir modülü tasarlandığı göreve odaklamak
- Modülleri diğer sistemlerin yaptıklarını nasıl yaptıklarıyla ilgili varsayımlardan kurtarmak ve bunun yerine sözleşmelere güvenmek
- Bir modülü değiştirirken yan etkileri önlemek
- Test edilebilirliği arttırmak
Aşağıdaki örnekle en yaygın kullanılan ve bazı framework’ lerin varsayınlan olarak desteklediği Dependency Injection yöntemi aktarmaya çalışacağım.
Dependency Injection; bir nesnenin başka bir nesne tarafından davranışları bilinmeden ve davranışlarından etkilenmeden kullanılabilmesi tekniğidir. Bu örnekte Order sınıfının Complete metodunda müşteriye e-posta atabilmesini gerçekleştirdiği varsaydım.
Dependecy Injection için 3 yöntem;
- Constructor Injection
En çok kullanılan Dependency Injection yöntemidir. - Property Injection
İhtiyaç duyulan nesnenin değer atanabilir bir property üzerinden kullanılabilmesidir. Dikkat; NullLogger dışarıdan hiçbir değer atanması durumnda çıkabilecek NullReference hatasının önüne geçilmek için yapılmıştır. - Method Injection
Her metot çağrımında değişen bir bağımlılık varsa bu yöntem faydalı olabilir.
Sonuç olarak,
Yazılım tarihinden bu yana halen ilkel veri tiplerini kullanmamıza rağmen biz geliştiriciler onu karmaşıklaştırıyoruz. Bu karmaşa bağımlılıkları ortaya çıkartır, zamanla geliştirilmeye devam yazılımın bağımlılıklarını iyi yönetmek için bazı yaklaşımlar uygulamalıyız. Bu yazıda uygulama için bağımlılıklardan bahsetmeye çalıştım. Peki ya diğer bağımlılıklar neler ?
Kaynaklar;
https://en.wikipedia.org/wiki/Technical_debt
https://java-design-patterns.com/principles
https://en.wikipedia.org/wiki/Dependency_injection
https://www.martinfowler.com/articles/injection.html
https://www.martinfowler.com/bliki/InversionOfControl.html
https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/architectural-principles