Yazılım Karmaşıklığı ve Değişim – I

Yazılımın en temel iki özelliği, karmaşıklık ve değişmedir.Yani yazılım ürünleri aşırı karmaşık ve çok sık değişmesi gereken yapıdadırlar. F. Brooks, “No Silver Bullet” isimli makalesinde, yazılımın asli (essential) özelliklerinden bahsederken, diğer iki özelliğinin yanında (görülemezlik (invisibility) ve uyumluluk (conformity)) karmaşıklık ve değişebilirlikten bahseder. Görülemezlik ve uyumluluk özelliklerini, karmaşıklığın ve değişebilirliğin sebeplerinden birer tanesi olarak görürsek, “yazılım asli olarak karmaşık ve değişebilirdir” diyebiliriz.

Yazılım, soyuttur, kavramsaldır, görünmezdir, dolayısıyla anlaşılması ve anlatılması zordur. Yazılımın genelde örneği yoktur; aynı türden yazılım olsa bile farklılıkları çok fazladır, dolayısıyla birinden diğerine geçiş yapmak ya da birinden diğerini türetmek imkansızdır. Çünkü yazılımın bileşenleri kendi başlarına özeldirler, benzerleri yoktur. Bu anlamda yazılımda aynı “şey”den (satır, blok, metot, sınıf, dosya, modul, vs.) iki tane olması istenmeyen bir durumdur. Zaten eğer iki şey benzer ise birleştirilirler. Tekrar kullanılabilirlik bu yüzden son derece zordur. Dolayısıyla yazılımların büyümesi var olan bileşenlerin büyümesiyle değil de yeni ve orijinal bileşenlerin eklenmesiyle gerçekleşir.

Yazılım sistemlerinin bütün durumlarını (state) düşünmek, elde etmek, test etmek, dokümante etmek vs. imkansızdır. Çünkü, soyut kavramların durumlarını belirlemek genel olarak ya çok zordur ya da imkansızdır.

Yazılımların bileşenleri arasındaki ilişkiler de doğrusal (linear) değildir. Fiziksel dünyada, sistemler fiziksel kısıtlarla çevrelendiğinden, alt sistemler ve parçalar arasındaki ilişkileri kontrol altında tutmak mümkündür. Örneğin, bir aracın kasasının, tekerleklerle olan bağlantısı, son derece basit, standart ve akıllıca tanımlanmıştır öyle ki bu standartlara her araç ve jant üreticisi uyar; böylece aracınızı nereden almış olursanız olun, istediğiniz yerden jant ya da lastik alıp, aracınıza takabilirsiniz. Aracınızın tekerleklerini değiştirmek, sileceklerde ya da akaryakıt filtresinde bir etkiye sebep olmaz. Yazılımda durum nasıldır? Yazılım sistemlerindeki karmaşıklık öylesine büyüktür ki aynı karmaşıklığa araçlarda sahip olsaydık muhtemelen bir tekerleğin çalışmasını anlamak için bujiden tutun da sileceklere, kaportadan tutun da antene kadar pek çok şeyi anlamamız gerekecekti.

Benzer durum değişim için de geçerlidir. Son derece karmaşık yapıdaki yarış arabalarının bir yarış esnasında dört tekerleğini değiştirmek 15-20 saniyede yapılabiliyor. Benzer karmaşıklıktaki bir yazılımın, tekerleğe karşı gelen, benzer büyüklükteki bir modülünü bırakın tamamen değiştirmeyi, böyle bir yazılımın en basit bir tarafıni bile değiştirmek günler hatta haftalar sürebilir. Karşılaştırma yapmak zor, farkındayım, ama uğraştığımız alanın kendine has özelliklerini anlamak ancak böyle kıyaslamalı örneklerle mümkün oluyor. Bu anlamda eğitimlerde çok sıklıkla tekrarladığım bir örneğim vardır: “Geçenlerde arabamın lastiklerini değiştirttim. Sonra yolda geri dönerken yağmür yağmaya başladı ve silecekleri çalıştırdım. Ama baktim ki silecekler çalışmıyorlar. Ne olabilir diye düşünürken aklıma lastikleri değiştiren ustayı aramak geldi. Belki orada bir şey olmuştur diye düşündüm. Usta da bana, ‘evet Akin abi, lastikleri değiştirince ilk bir – iki saat silecekler çalışmaz’ dedi.” Böyle bir şey yaşasak herhalde ustam şaka yapıyorsun değil mi deyip karşılıklı gülerdik. Peki böyle bir durum bir yazılım sisteminde olsa, hiç bir yazılımcıyı hiç şaşırtmaz ama. Çünkü, yazılımın parçaları arasındaki bu türden, kontrolsüz bir şekilde kurgulanmış ilişkiler o kadar yaygındır ki, aksini düşünmek zordur.

Fiziksel dünyada değişimi kolaylaştırmak amacıyla, sık değişecek şeyler kolay değişecek şekilde tasarlanmışlardır. Değişmesi zor olan parçalar genelde pek de sık değişmeyecek parçalardır. En sık değişen parçaları, işinin ehli olmayan insanlar bile değiştirebilirler. Ama örneğin trigger kayışı (ya da timing belt), genelde 60.000, 80.000 km gibi aralıklarla değiştiğinden, değişimi zor ve zaman alan bir parçadır.

Karmaşıklık

Robert E. Wood, 1986 yılında yayınladığı bir “Task Complexity: Definition of The Construct” isimli makalesinde, bir işin teorik yapısında üç parça olduğunu ifade eder:

• İşin ürettiği çıktılar (products)

• İşin yapılması sırasında gerekli işler (işlemler) ve davranışlar (required acts)

• İşin yapılması sırasında karar verirken gerekli bilgi parçaları (information cues)

Bu teoriyi yazılım sistemlerine uyguladığımızda, yazılımın karmaşıklığının sırasıyla en temel üç faktörü olarak şunları sayabiliriz:

• Program parçalarının karmaşıklığı: nesneler, metotları ve aralarındaki statik ilişkiler (temelde bilme ilişkisi),

• Program girdileri ve çıktıları arasındaki kamaşıklık: girilen veriler ve eventler ile üretilen hizmetler, GUI yapıları, nesne, veri, rapor, vs. arasındaki yapı, d.nüşüm ve işlemlerle ilgili karmaşıklık (zamansal, prosedürel ilişkiler),

• Veriler ve bilgi karmaşıklığı: işlenen veri yapılarının durumları ile sahip olunması gereken bilginin karmaşıklığı.

Bu üç karmaşıklık faktörünü şu şekilde de ifade edebiliriz:

Bileşen Karmaşıklığı = Program parçalarının karmaşıklığı + Veri/bilgi karmaşıklığı
Koordinasyon Karmaşıklığı = Program girdileri ve çıktıları arasındaki kamaşıklık

Bileşen karmaşıklığı, bileşenin alt parçalarının ne kadar “birlikte” (cohesive) olduğunun bir ölçüsüdür. Yani bir bileşen, ne kadar birlikteliği yüksek ise o kadar az karmaşıktır. Birliktelikten kasıt ise tek bir şeye odaklılıktır. Bir yazılım bileşeni, ister bir satır olsun ister bir blok, ister bir metot isterse de bir sınıf olsun, hatta isterse bir bileşen olsun, tek ama tek bir şeye odaklı olmalıdır. Birliktelik İngilizce’de cohesion olarak ifade edilir ve arzu edilen şey, highly-cohesive yani yüksek birliktelikli yapılardır çünkü karmaşıklıkları düşüktür.

Yüksek birliktelikli yapılar, aynı yerde birden fazla şeyi halletmeye çalışmazlar, sadece bir şeyi ama her yönüyle halletmeye odaklanırlar. Bu anlamda Osmanlıca’da tanımın tanımı olarak verilen “efradını cami ağyarını mani” sağlıklı nesneler için de geçerlidir. Yani nesneleriniz öyle olmalıdır ki bir konuyla ilgili her şeyi hallederken, ilgisiz olan hiç bir şeye de bulaşmamalıdır. Birlikteliği düşük sistemlerin anlaşılması, kodlanması, bakımı, testi, dokümantasyonu vs. hepsi çok daha zordur.

Koordinasyon karmaşıklığı, bir işin ne kadar kendi başına ifade edilebilirliğinin ya da diğerleriyle ne kadar “ilgili” olduğunun ölçüsüdür. İlgililik, diğerleri hakkında bilgidir yani bağımlılıktır (coupling) ve bağımlılığı düşük olan bileşenlerin karmaşıklığı da düşüktür. Bir bileşen oalbildiğince sadece ve sadece kendi hakkında bilmelidir, diğerleriyle ilgili bilgisi ise olabildiğince minimal düzeyde kalmalıdır. Bağımlılık İngilizce’de coupling olarak ifade edilir arzu edilen şey, lowly-coupled yani düşük bağımlılıklı yapılardır çünkü karmaşıklıkları düşüktür. Dolayısıyla, çevresindeki diğer nesnelerle alakası, bilgisi az olan nesnelerın bağımlılıği düşüktür, bu yüzden böyle nesneler daha kolay anlaşılır, aktarılır, kodlanır, test edilir ve dokumante edilirler.

Bu anlamda, gerek karmaşıklığı gerek ise değişimi yönetebilmek için yüksek birliktelikli ve düşük bağımlılıklı (highly-cohesive and lowly-coupled) yapılar kurgulamalıyız.

Bu yazı toplam 1208 defa görüntülenmiştir.