Sizce bir yazılım projesinde en çok kimin sözü geçer? Programcıların mı yoksa proje yöneticisinin mi? Kimin izin verdiği kadar iş yapılır? Kim ne derse, o olur? Kim en çok yazılımcıların gözünü korkutur? Kim “istemem” deyip, masaya yumruğunu vurduğunda, herkesin yüreği ağzına gelir? Kim olabilir ki bu demeyin. Her projede böyle bir diktatör ya da bir canavar var. Tüm proje ekibi el ele vererek, onu ekibe dahil olması için çalışırlar. Bu şahsiyeti şimdi yakından tanıyalım.
Ekip oluşturulur, başına bir Scrum master ya da proje yöneticisi konur, sırtlar sıvazlanır ve projeye başlanır. Bahsettiğim canavar o gün doğar ve ekibin bir parçası haline gelir. Sonraki evrelerde onun ağırlığı hissedilir, onun istediği, izin verdiği şekilde hareket edilir, ondan çekinilir, hatta korkulur.
Projenin ilk birkaç haftası lay, lay, lomlar eşliğinde geride bırakılır ve aniden bir şeyin farkına varılır: o da ne, hiç hesapta olmayan birisi toplantı masasında oturuyor! Kim davet etti ki bunu diye sorulmaz, çünkü o sessizce ekibin bir parçası haline gelmiştir. İlk haftalarda pek sesini çıkarmaz o şahsiyet. Yanaşmadır, fazla ses çıkarmadan hayatını sürdürmeye, yani büyümeye çalışır. Büyüdüğünde ekibe ne zulümler yapacağını planlar, ama bundan kimseye bahsetmez. Maksadı çaktırmadan büyümektir. Henüz küçük olduğundan kimse onu kale almaz.
Proje ilerledikçe bir kenarda yanaşma gibi duran canavarcık büyür ve yavaş yavaş ağırlığını ortaya koymaya başlar. Artık proje bünyesinde ağırlığı hissedilir hale gelmiştir. Yazılımcılar onun istediği şekilde hareket etmeye başlarlar. O kırbacı eline alır ve herkesi istediği şekilde terbiye etmeye başlar. Yavaş yavaş kafa koparma operasyonlarına da başlamıştır. İstediğini projeden attırır, çünkü o kadar büyümüştür ki artık, ona kimse yan gözle bile bakmaya cesaret edemez. Onu adam etmek isteyen herkes ya işinden olur ya kendiliğinden çeker gider, çünkü adam olma şansı çok düşüktür. Çok asabi olduğundan, ona yaklaşmak mümkün değildir. Artık ofiste herkes ondan korkusundan fısıldaşarak konuşmaya başlanır. Herkes onun zulmünden korkar. Fazla mesailerin yegane sebebi odur. Herkes ondan nefret eder, ama onunla yaşamak zorundadırlar, çünkü projenin canavarı o dur.
Yoo! Bilim kurgu yazıları yazmaya başlamadım. Ben gerçeklerden bahsediyorum, kendi ellerimizle büyüttüğümüz o canavardan. Şu kadar yıldır yazılımla uğraşıyorum ve o canavarın olmadığı proje görmedim. İşin komik tarafı, programcıların o canavarı kendi elleriyle beslemeleri ve büyüdüğünde ona ellerini kaptırmaktan korkmalarıdır, çünkü onu elleriyle beslemeye devam etmek zorundadırlar. O böylece büyümeye devam eder ve o kadar büyür ki tüm ofisi kaplar. O canvarın ismi yazılım ürünü, software, program vs. dir.
Oluşturduğu şeyden korkan tek meslek grubu sanırım programcılar. En iyi niyetlerle projeye başlar programcılar, ama bir zaman sonra bakarlar ki karşılarında onları sürekli ısıran, tartaklayan bir canavar oluşmuş. Bunun böyle olduğuna “bu işin ustasıyım, çeviğim, acayip bir ürün ortaya koyacağım” diyen programcılarda bile sahit oldum. En çevik programcı olsanız bile, bir zaman sonra nedense oluşan program içinden çıkılamaz hale geliyor. İstediğiniz kadar design pattern, design principle, integration pattern ya da test driven development kullanın, sonuç hep aynı olacaktır, çünkü yapısı itibari ile çevik olmayan bir şeyi yoğurmaya çalışıyorsunuz. Sizin değil, onun çevik olması gerekiyor ki sizi çevikleştirebilsin.
Projenizdeki bahsettiğim canavarı bir aslan olarak düşünün. Onunla karşı karşıya gelindiğinde, kimin kaybedeceği malum. Peki karşınızda bir aslan yerine 10 tane kedi olsaydı, durumu nasıl değerlendirirdiniz? Kedilerden korkmayacağınız gibi, onlarla baş etmeniz daha kolay olacaktır. Önemli olan yazılım ürününün aslana dönüşmesini engellemek ve kedi olarak kalmasını sağlayabilmektir. Bunu nasıl yapabiliriz?
Agaç yaşken eğilir atasözünü hatırlayalım. Kodu hamur olarak düşünürsek, yoğrulabilmesi için yaş olması gerekir. Hamura şu kattığımız sürece, hamuru istediğimiz şekle sokabiliriz. Aynı şey kod parçaları için de geçerlidir. Testleri olan bir kod parçasını istediğimiz şekilde yeniden yapılandırabiliriz. Yazılım ürünü hamur, testler ise hamuru yoğurduğumuz sudur. Kuruyan hamuru yoğurmak mümkün değildir, aynı şekilde testleri olmayan bir uygulamayı müşteri gereksinimleri doğrultusunda yeniden yapılandırmak imkansızdır. Bu yüzden programcılar bir zaman sonra uygulamayı değiştirmeye cesaret edemezler. Ellerinde kaskatı olmuş bir hamur parçası vardır. O zamanla büyür ve bahsettiğim canavar haline gelir.
Testler müstakbel canavarı ehlileştirmek ya da oluşmasını engellemek için kullanılabilecek yöntemlerin başında gelmektedir, lakin tek başlarına canavarın oluşmasını engelleyemezler. Bu canavarın üzerine birkaç koldan gitmemiz gerekir ki oluşması önlenebilsin. Hangi yöntemleri kullanabiliriz?
Böl ve yönet taktiğinden bahsettim. Bir aslan yerine on tane kedi ile karşı karşıya kalmayı tercih ederim. Aslanın benim yaptıklarımdan beslenmesini önlemek için oluşmasını engellemem gerekir. Yazılımda bunun karşılığı modüler yapılardır. Koca bir gökdelen inşa etmek yerine, birçok villadan oluşan bir site inşaatı gibi düşünebiliriz yazılımı.
Canavarın oluşmasını engelleyecek diğer bir yöntem ise, ona verilen zihnin ya da aklın (intelligence) sınırlandırılmasıdır. Bunu KISS yöntemiyle sağlayabiliriz. Çözüm ne kadar basit ise, kod o oranda daha az karmaşık olacaktır. Karmaşık olan kod bahsettiğim canavarı güçlendirir, onun zekasını ve bize hükmetme kabiliyetini artırır. Bu canavarın kodun içindeki karmaşadan beslendiğini söylemek yanlış olmaz. Bunun önüne geçmek için mümkün olan en basit çözümü seçmemiz gerekmektedir.
Şimdi kısa bir özet yapalım. Canavarın oluşmasını ya da büyümesini engellemek için yapmamız gerekenler:
- Bol bol test yazmak.
- Gökdelen tasarlamak yerine, uygulamayı parçalara yani modüllere bölmek ve tek katlı konutlar yapmak. Uygulama bu modüllerin birleşiminden bir araya gelen bir ürün olmalı.
- Mümkün olan en basit çözümü uygulamak.
Bu yazdıklarım ne yazık ki canavarın oluşmasını engelleyen bir reçete değil. Bu listeye bir kalem daha eklememiz gerekiyor:
- Kodun ne durumda olduğunu bize gösteren araçlar kullanmak
Orta ve büyük çaplı projelerde ne kadar iyi niyetli olursanız olun, yazdığınız testlerin kapsama alanı (code coverage) %100 de olsa, test güdümlü yazılım bile yapsanız, kod karmaşa (complexity) seviyesi kaşla, göz arasında artabilir. Bu proje canavarını hemen hortlatır. Bunun önüne geçmek için kodun ne durumda olduğunu gösteren metriklerin sürekli göz önünde bulundurulması gerekmektedir. Bunlardan bazıları:
- Cyclomatic complexity değeri (örneğin iç içe geçmiş kaç if dalı bulunmakta? Bu değer ne kadar yüksekse, kod o oranda problemlidir.)
- Paketler arası döngü (Kodun bağımlılık oranını artırır.)
- Modüller arası döngü (Modüllerin tek başlarına iş yapmalarını ve tekrar kullanımı engeller)
- Sınıf başına düşen kod satır sayısı (ne kadar düşükse, kod o kadar az sorumluluğa sahiptir.)
- Kod tekrar adedi (Ne kadar yüksekse, kod o oranda kırılgandır.)
- Kalıtım derinliği (Kalıtım hirarşisi derin kodun bakımı ve geliştirilmesi zordur.)
Bahsetmiş olduğum bu metrikler kodun hangi statiksel yapıda olduğunu gösterir niteliktedirler ve sürekli göz önünde bulundurulmaları gerekmektedir. Bunu Sonar gibi bir araç yardımı ile yapabiliriz. Sonar FindBugs, PMD, Checkstyle, JaCoCo gibi araçların bir araya geldiği bir kod statik analiz aracıdır. Gerrit ve Jenkins gibi araçlarla birlikte kullanıldığında, kodun ne durumda olduğu bilgisi ekip içinde sürekli paylaşılan bir bilgi haline gelecektir.
Ne yazık ki kod yapısı itibari ile büyümeye eğilim gösteren bir şey. Her yeni müşteri isteği ile bu büyüme süreci desteklenmektedir. Bu gidişata dur demenin tek yolu, kod büyümeden parçalarına bölmek ve dikey değil, yatay büyümesini sağlamaktır. Dikey büyüyen kod zamanla bahsettiğim canavara dönüşecektir. Kod yatay büyüyorsa, o zaman bahsettiğim kediler ortaya çıkar ki onlarla baş etmek daha kolaydır.
Kod ne yazık ki büyümek zorunda, çünkü her yeni müsteri istediğinin hayata geçirilmesi gerekiyor. Kodun yatay büyümesini mümkün kılmak için SRP, OCP ve DIP gibi tasarım prensiplerinden faydalanabiliriz. Eğer test yazılımı ihmal edilmezse, yatay büyüme desteklenirse ve gidişat Sonar ile göz önünde tutulursa, ortaya çıkan şeyin çevik bir yazılım ürünü olduğunu söyleyebiliriz, çünkü her yeni müşteri isteği ile yeniden yapılandırılması mümkündür.
Benim bu noktada aklıma bir soru geldi, sizinle paylaşayım. Yazılım ürününü çevik yapan çevik yazılımcı mıdır yoksa yazılımcıyı çevik olmaya zorlayan çevik bir yazılım ürünü müdür? Bu konuda biraz düşünelim…
Ben yazılımcıyı çevikleştiren durumun yazılım ürününün çevik olmasından kaynaklandığını düşünüyorum. Yazılımcılar ne kadar çevik olurlarsa, olsunlar, üzerinde çalıştıkları yazılım ürünü yoğrulmaya izin vermiyorsa, yani çevik olma özelliklerine sahip değilse, bir zaman sonra çevik yazılımcılar gidişata uyak uydurarak, canavarın hakimiyetine boyun eğerler. Buna karşın bahsettiğim çevik özelliklere sahip bir yazılım ürünü programcısını çevik olmaya zorlayacaktır, çünkü programcının çevik olabileceği ya da olmak zorunda olduğu bir ortam mevcuttur. Önemli olan işte böyle bir ortamı oluşturabilmek. Geliştirilen uygulama da ekibin bir parçasıdır. Bu tüzel kişinin nasıl bir karakterde olacağını geri kalan yazılımcılar belirler.
Canavarla karşılaşmamanız dileğiyle..
EOF (End Of Fun)
Özcan Acar
Yorumlar
“Programcıların Besleyip, Büyüttükleri Canavar” için 2 yanıt
Hocam elinize sağlık gerçekten güzel bir makale olmuş tek solukta okudum. Böl ve yönet 😉
Maşallah hocamız yazının hakkını vermiş doğrusu ve çok faydalı bir yazı olmuş.
teşekkürler…