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.
Toplam görüntülenme sayısı: 1826
Mehmet
05 Haziran 2014 @ 12:00
Yazılım karmaşıklığı makaleniz, hep tartışılan yazılım “mühendislik midir?” “sanat mıdır?” sorusunun cevabı olarak, bende yazılımın hem sanat hem de mühendislik olduğu kanısına vardırdı.
Çünkü birden çok sanatkara aynı girdiyi verip aynı çıktıyı isteseniz bile herbir sanatkar birbirinden çok farklı şekilde eser üretecektir ve sanatını yaparken farklı yöntemler ve kişisel beceriler kullanacaktır. Ayrıca eserindeki küçük bir yerdeki değişim bütünde çok çabuk fark edilecektir.
Yazılımda da herbir yazılımcıya aynı girdiyi verip aynı çıktıyı bekleseniz bile aynen sanatkarlarda olduğu gibi olacaktır ve farklı çıktılar olacaktır.Kişisel bilgilere dayalı olarak da farklı şekilde sonuca erişimler olacaktır. İşte tam bu noktada tasarım şablonları ile yazılım sanattan uzaklaşarak mühendisliğe yanaşabilir. Yazılıma konusuna uygun belirli tasarım şablonları uygulanarak yüksek birliktelik ve düşük bağımlılık sağlanır ve bu şekildeki mühendislik disiplinleri ile yazılmda yapılan bir değişikliğin diğer parçalara olan etkisi azaltılabilir.
Bilmem katılır mısınız:)
Akin
05 Haziran 2014 @ 13:10
Katiliyorum tamamen Mehmet sana. Sadece sahsi tecrubeler uzerine kurulmus gelistirme yapmak yerine daha objectif, aktarilabilen, olculebilen kriterler ortaya koymak, yaptigimiz isi muhendislige yaklastiracaktir. Design patternlar bence bunun baslangic noktasi.
Tesekkur ederim.