Kalite#7-Bileşenler Arası İlişkiler (The Acyclic Dependencies Principle)

mehmet baran
Bilişim Hareketi
Published in
4 min readOct 1, 2018

Bileşenleri kurgulamak yazısında ve devamında yazdığım iki(1, 2) yazıda hangi sınıfların hangi bileşenlere koyulması gerektiği ile ilgili prensiplerden bahsetmiştim. Bu prensiplerden 2’si sınıfları bir araya getirerek bileşenleri büyütmeye meyilli iken diğeri ise bileşenleri küçültmeye meyilli idi. Dolayısı ile doğru kullanıldıklarında bir denge oluşturacaklarından bahsetmiştik. Daha detaylı incelemek için özellikle son yazıyı okuyabilirsiniz.

Bileşenleri kurguladığımıza göre bir sonraki aşama olan bileşenler arası ilişkileri düzenlemeye geldik. Yeni bir projeye başlarken her ne kadar kağıda dökmesek bile hepimiz bileşenler arası bağımlılıkları kafamızda kurarız. Hangi bileşenin hangisine bağımlı olacağına geçmiş deneyimlerimize göre karar vermeye çalışırız. İşte bu konuda da çok uzun yıllarda elde edilen deneyimlere dayanarak geliştirilen bazı prensipler var. Bu yazıda ve önümüzdeki 2 yazıda bu prensipler üzerinde duracağız.

ADP: The Acyclic Dependencies Principle

Projelerimizi bileşenlere bölerek yönetmek bize birçok açıdan avantajlar sağlar. Her bir bileşenden sorumlu bir takım veya tek bir geliştirici olabilir. Böylece görevler ve sorumluluklar daha kolay yönetilebilir. Peki bileşenler arası bağımlılıklardan dolayı oluşan birlikte çalışma zorunluluğu nasıl yönetilecek? Bir bileşende değişiklik yapıldığında bağımlı bileşenlerin de hemen yapılan değişikliğe adapte olması gerekir. Sonra onlara da bağımlı olanların aynı şekilde adapte edilmesi gerekebilir. Bu değişim silsilesi kendisine bağımlı bileşen bulunmayan en tepe bileşene kadar devam eder. Bu süreçte birçok geliştirme, test, derleme ve yaygınlaştırma işlemi yapılması gerekir ve bunlar çok ciddi maliyetlerdir.

Yukarıda basit bir frontend uygulamasının mimarisi çizmeye çalıştım. Bu çizimde bileşenler kutularla belirtildi ve bileşenler arası bağımlılıklar oklarla gösterildi. Diyagrama göre IOC katmanında yapacağımız herhangi bir değişiklik sistemdeki tüm bileşenleri etkileyecektir. Fakat Container bileşeninde yapacağımız bir değişiklik ise sadece Application bileşenini etkileyecektir. Etkilenen her bir bileşenin test edilmesi, derlenmesi ve yaygınlaştırılması gerekir. Dolayısıyla değişimlerin etkileri sandığımızdan çok daha maliyetli olabilir.

Allow no cycles in the component dependency graph

İşte böyle bir yapının sağlıklı çalışmasının en öncelikli gereksinimlerinden birisi bağımlılıkların asla döngü oluşturmamasıdır. Yani bir bileşen, kendisine bağımlı olan bileşenlere dolaylı yollardan dahi bağımlı olmamalıdır.

Diyagrama bakarak ayrıca derleme ve test sıralamasını da görebilirsiniz. Sizler de projerinizin mutlaka bağımlılık diyagramlarını çıkarmalısınız bence.

Şimdi bizden talep edilen işten dolayı döngüye sebep olacağımız bir değişiklik yapalım diyagramda. IOC bileşeninin Authorization bileşeninde bulunan bir User sınıfını kullanması gerektiğini düşünelim.

Kırmızı okla gösterdiğim yeni eklenen bağımlılık ilk bakışta sorun yokmuş gibi gösteriyor kendini. Zaten aralarında ilişki olmayan iki bileşen ilk defa birbirlerine bağımlı hale geliyorlar. Fakat Store bileşenini de işin içine katınca bir döngü oluştuğu görülebilir. Bu döngünün zararları şu şekilde sıralanabilir.

  1. Derleme Sorunları: IOC, Authorization ve Store bileşenlerinden hangisini değiştirirseniz değiştirin hepsinin derlenmesi gerekir. Ama döngüsel bağımlılıktan dolayı derlemek çok kolay olmayacaktır.
  2. Test Sorunları: Özellikle entegrasyon testlerinin tamamlanması için bağımlılıkların da test edilmesi gerekir. Ama yine döngüsel bağımlılıklardan dolayı test süreçleri de döngüye girecektir.
  3. Yaygınlaştırma Sorunları: Döngüden dolayı bağımlılıkların versiyonlarını yönetmek karmaşıklığa sebep olabilir. Sistemde bir bileşenin farklı versiyonlarının aynı anda çalıştırılması gerekebilir.

Döngüyü Kırma Yolları

a. Bağımlılığa sebep olan sınıfları yeni bir bileşene taşıyarak döngünün önüne geçilebilir. Bizim örneğimizde Authorization katmanındaki User sınıfı bağımlılığa sebep olmuştu. User sınıfını Entities adında yeni oluşturduğumuz bir bileşene koyarsak döngü sorununu ortadan kaldırmış oluruz.

b. Bağımlılığı ters çevirme yöntemi(D of SOLID — Dependency Inversion Principle) ile bağımlığın yönünü IOC’den Authorization yerine tam tersi olacak şekilde ayarlayabiliriz. IOC bileşenine IUser adında bir interface ekleyip Authorization bileşenindeki User sınıfını ise bu interfaceden implemente edersek bağımlılık terse dönmüş olacaktır. Bağımlılık yönünü ters çevirdiğimize göre artık döngü oluşmayacaktır.

Büyük projelerde bağımlılık diyagramı baştan çizilmeli ve sürekli olarak güncel tutulmalıdır. Böyle bir diyagram derleme sıralaması, testler, yaygınlaştırma ve etki analizi gibi birçok konuda bizlere yardımcı olacaktır. Projeler büyüdükçe dikkatlerden kaçan bağımlılık döngüleri oluşabilir. Güncel ve izlenen bir diyagram sayesinde bunun önüne geçilebilir.

(*) Robert C. Martin, Clean Architecture

--

--