Kod Basitliği — 3
Yazılım Tasarımının İtici Güçleri
Yazılım yaparken, neden onu yapmamız gerektiği ve son hedefimizin ne olduğu ile ilgili düşüncelerimiz olmalıdır.

- Bu yazı Code Simplicity kitabından alıntıdır. Orjinal halini buradan alabilirsiniz.
- Yazının öncesini buradan okuyabilirsiniz.
Bütün yazılımların amacını toplayabilme yolumuz var mıdır? Böyle bir ifade olsaydı, yazılım tasarımı bilimine katkı yapabilirdi.
Aslında, bütün yazılımların tek bir amacı olduğunu söyleyebiliriz: İnsanlara yardım etmek.
Bazı yazılımlar bireysel kullanıcıların faydalanması içindir. Örneğin, kelime işlemcileri bir şeyler yazmak içindir, web tarayıcısı da insanların Web’te gezinmeleri içindir.
Bazı yazılım parçaları sadece belirli bir grup insanlara yardım etmek için vardır. Örneğin, muhasebe yazılımları muhasebeciler içindir.
Önemli bir nokta, yazılım hiçbir zaman cansız nesnelere yardım etmek için olmamıştır. Yazılım bilgisayarlara yardım etmek için değil, insanlara yardım etmek için vardır. Kütüphane yazarken bile, başka programcılara yardım için bunu yaparsınız.
“Yardımdan” kasıt nedir? Bu bir açıdan özneldir. Bir insana yardım etmek diğerine yardım etmemek olabilir. Yine de kelimenin bir sözlük anlamı vardır,
bir insana, bir şeyi yapabilmesi için kolaylaştırmak
Yardım edebileceğin birçok şey var, ne olduğu sana kalmış ama amaç her zaman yardım etmek.
Yazılımın amacı, “para kazanmak” veya “ne kadar zeki olduğunu göstermek” değildir. Bunları tek amaç edinerek yazan herkes, yazılımın amacını ihlal etmiş olur. Bunlara kendi kendine yardım etmek diyebiliriz ama bu yardımın kapsamını oldukça kısıtlamak olur. Sadece bu amaçlarla üretilen yazılım düşük kalite yazılıma götürür.
Başkalarına yardım etme düşüncesi olmayan insanlar kötü yazılımlar geliştirirler. Aslında, şöyle teorileştirebiliriz, iyi bir yazılım geliştirme yeteneğin, başka insanlara yardım etme düşüncesinin kapsamı kadar sınırlıdır.
Genel olarak, yazılım hakkında karar alırken, bizim yönlendirici prensibimiz “nasıl yardım edebiliriz” olmalıdır. Hatta, istenilen taleplere de buna göre öncelik sıralaması verebiliriz. Hangi özellikler insanlara en çok yardımı yapar? Bu özellik, en öncelikli olmalıdır.
İnsanlara yardım etme amacı, yazılım geliştirirken ve gerçek yazılım tasarımı bilimi oluştururken, akılda tutulması gereken en önemli şeydir.
Yazılım Tasarımının Amacı
Artık yazılımın amacını biliyoruz, buradan bizim yazılım tasarımı bilimine biraz yönlendirme yapabiliriz.
Yazılım tasarım biliminin hedeflerinden biri şu olmalıdır,
1. Mümkün olduğunca yardımcı olabilecek yazılım geliştirmek.
İkinci olarak, insanlara, bizim yazılımımız tarafından, yardım etmeye devam etmek isteriz.
2. Mümkün olduğunca yardımcı olmaya devam edecek bir yazılım geliştirmek.
Bu güzel bir hedef ama herhangi bir büyüklükte yazılım karmaşık olabiliyor, bu yüzden, zamanla yazılımın yardımcı olmaya devam etmesi zor bir görevdir. Aslında, günümüzde faydalı bir yazılım geliştirmek ve onun bakımını sağlamak, tasarım ve programlamanın asıl zorluğunu oluşturuyor. Yazılım oluşturmak ve değiştirmek zor olduğunda, programcı zamanının çoğunu “sadece çalışsın” hale getirmek için harcıyor ve kullanıcılara yardım etme kısmını es geçiyor. Kod yazmak ve geliştirmek basit hale gelirse, programcı yazılımın yardımcı olma kısmıyla daha çok ilgilenir. Bu da bizi üçüncü amacımıza götürür,
3. Programcılar tarafından, mümkün olduğunda kolay oluşturulup geliştirilen sistemler tasarlamak, sistemin mümkün olduğunca faydalı olacağını/olmaya devam edeceğini gösterir.
Bu üçüncü amaç geleneksel olarak, her ne kadar açıkça bahsedilmese de, yazılım tasarımın amacı olarak düşünülür. Şimdi yardımcı olabilmek ve gelecekte de yardımcı olmaya devam etmek, bizim asıl motivasyonumuzdur.
Bazen, birinci hedef ile üçüncü hedef birbiriyle çelişebilir, bir yazılımı faydalı yapabilmek bakımını sağlamayı zorlaştırabilir. Bakımı yapılabilir bir sistem geliştirebilmek ve bunun kullanıcılara çok faydalı olması, kesinlikle mümkündür. Eğer bakımı sürdürülebilir değilse, ikinci maddede ki faydalı olmaya devam etmesi mümkün olmaz.
Gelecek
Yazılım tasarlayanların karşılaştığı temel soru, “Yazılımım hakkında kararları nasıl alacağım?” Birçok seçenekli ihtimalle karşılaştığında, en iyi seçenek hangisi olur? Bu hangi seçeneğin kesin tek doğru, hangi seçeneğin kesin yanlış olduğuyla ilgili bir soru olmaz. Onun yerine, bilmek istediğimiz şey, “Verilen birçok mümkün kararlar dahilinde, şu kararlar diğerlerinden daha iyidir.” Kararları sıralayıp, seçenekler arasından en iyisini seçebilmek meselesi.

Yazılım Tasarımının Denklemi
Yazılım tasarımındaki her soruya, şu denklemle cevap verilebilir,

D: Değişimin çekiciliğini(desirability, cazibesi) temsil eder. Ne kadar şey yapmak istiyoruz?
V: Değişimin değerini(value) temsil eder. Bu değişim ne kadar değerlidir?
E: Değişim için gereken eforu(effort) temsil eder. Değişim için ne kadar iş gerekiyor?
Aslında, bu denklem şunu der,
Herhangi bir değişimin çekiciliği/cazibesi, değişimin değeri ile doğru orantılıdır ve değişimi yapmak için gereken efor ile ters orantılıdır.
Çokça değer üretecek ve değişim eforu az olan değişimler, az değer üretip çok efor gerektiren değişimlerden daha iyidir.
D: Değer(Value)
Denklemdeki değer(value) ile neyi kastediyoruz? Değerin basitçe tanımını şöyle diyebiliriz,

Herhangi birine herhangi bir yerde yardımcı olan değişikliğin derecesi.
Yardım ettiğiniz en önemli kişiler, sizin kullanıcılarınızdır. Bununla birlikte, finansal olarak size destek olacak özellikleri de yazmanız bir bakımdan bir değerdir.
Bazen, herhangi bir değişimin tam sayısal değerini hesaplamak zordur. Örneğin, yazılımınıza insanların kilo vermesinde yardımcı olacağını söyleyin. Bunu yapamazsınız ama yazılımınızın bazı özelliklerinin insanlara daha çok bazılarınsa daha az kilo verdirdiğini bilebilirsiniz. Bu yüzden, yine de değişiklikleri değerlerine göre sıralayabilirsiniz.
Geliştirici olarak, her bir değişiklik ihtimalinin değerini anlamanız, genellikle deneyiminizden gelir ya da kullanıcılar ile ilgili yapacağınız araştırmalar ve en çok hangi özelliğin onlara en çok faydalı olduğunu öğrenmenizden gelir.
Değerin Olasılığı ve Potansiyel Değer
Değer iki faktörden oluşur, değerin olasılığı(bu değişiklik ne ihtimalle kullanıcıya fayda verecek) ve potansiyel değer(bu değişiklik kullanıcıya ne kadar fayda verecek).
Örneğin;
- Bir özellik, milyonda bir kere bile ihtiyaç olsa, bazılarının hayatlarını kurtarabilir ve çok değerli bir özelliktir. Yüksek potansiyel değeri olan ama olasılığı az olan bir özelliktir.
- Kullanıcıların %100 oranında, suratlarında gülümsemeye neden olacak bir özellik, değerli bir özelliktir. Potansiyel değeri az ama olasılık değeri fazla.
- Diğer tarafta ekleyeceğin özellik, milyonda bir insanların gülümsemesine neden oluyorsa, değerli bir özellik olmaz. Hem potansiyeli az olan hem de olasılığı az olan bir özellik.
Değeri düşündüğünüz zaman, şunları da düşünmelisiniz,
- Kaç tane kullanıcı için bu değişikliğin değerli olduğu?
- Bu özelliğin kullanıcıya değerli olma olasılığı? Yani, bu özellik ne sıklıkla değerli olacak?
- Değerli ise, ne kadar değerli olacağı?
Zararın Dengesi
Bazı değişiklikler getirdikleri faydanın yanında zarar da getirirler. Örneğin, bazı kullanıcılar yazılımınıza reklam eklemenizden rahatsızlık duyar, ki bu reklamlar sizi finansal yönden desteklese bile.
Burada değişikliğin değerinin ne kadar zarar getireceğini hesaplamak gerekir.
Kullanıcılara Sahip Olmanın Değeri
Kullanıcısı olmayan özelliğin değeri de olmaz. İlerde belki değeri olabilir ama şimdi bir değeri yoktur.
E: Efor(Effort)
Genellikle eforu şöyle tanımlayabiliriz, “belli sayıdaki insanlar tarafından belli sayıda saatte çalışarak yapılan iş.” “Senede 100 insan” efor için sayısal bir ölçüm örneğidir.
Eforu sayıların içine koyabilmemize rağmen, pratikte onu ölçümlemek oldukça zordur. Değişikliklerin gizli bir bedeli olabilir ve bunu tahmin etmek oldukça zor olur. Örneğin, ilerde hata ayıklama için harcayacağın zaman ne kadar olacak?
Değişim içinde, eforu düşünürken sadece programlama yapacağın zamanı düşünmemek gerekiyor, yaptığın araştırmalara ne kadar zaman harcadın? İşini yapabilmen için başka geliştiricilerle ne kadar süre iletişime geçtin? Değişikliği yaparken ne kadar süre onun üzerinde düşündün?
Değişimde, zamanla ilgili her bir parça, efor maliyetinin bir parçasıdır.
Bakım(Maintenance)
Gösterdiğimiz denklem aslında basittir ama eksik önemli bir unsuru vardır, o da zamandır. Sadece değişikliği gerçeklemek değil, zamanla onun bakımını sağlamak da gerekir. Bütün değişiklikler bakım gerektirir. Örneğin, insanların vergileri için bir uygulama geliştiriyorsanız, her yıl değişen yeni vergi kanunları için uygulamanızı güncellemeniz gerekir. Şu anda olmasa bile, uzun-dönem bakım maliyeti olmayan değişimlerin bile bir maliyeti vardır.
Değeri, şimdiki zaman ve gelecek zamanı hesaba katarak düşünmeliyiz. Bazı değişiklikleri sisteme uygulamak, şimdiki kullanıcılarımıza yardımcı olacaktır diğer yandan gelecekteki kullanıcılarımıza da yardımcı olacaktır.
Bazı özelliklerin değeri zamanla değişir. Örneğin, 2009 vergi kanunlarıyla ilgili bir program, 2009 veya 2010 yıllarında değerlidir ama 2011'den sonra pek değeri kalmaz. Bunun aksine, bazı özellikler zamanla daha da değerlenebilir.
Bu gerçeklere bakarak, eforun gerçekleştirme eforu ve bakım eforunu kapsadığını söyleyebiliriz. Değer de aynı şekilde, şimdiki değer ve ilerdeki değerinden meydana gelir. Denklem ile şöyle gösterebiliriz,

E: efor(effort)
i: implementation(gerçekleştirim)
m: maintenance(bakım)
V: value(değer)
n: now(şimdi)
f: future(gelecek)
Tüm Denklem
Her şey eklendiğinde, tüm denklem şöyle olur,

Kelimelere dökersek,
Değişikliğin çekiciliği, günümüzdeki değeri ve gelecekteki değerinin toplamıyla doğru orantılıdır, ayrıca gerçekleme eforu ve bakım eforunun toplamıyla da ters orantılıdır.
Bu, yazılım tasarımının temel kanunudur.

