Tag Archives: cevik

Çevik Süreçler Neden Dikiş Tutturamadı

Çevik süreçlerin tam olarak ne olduğunu kavramamış, çevik süreçler ile bir proje uygulamamış, scrum yaparak çevik olduğunu ve çevik süreçlerin bir işe yaramadığını zanneden şahısların “agile is dead” naralarını unutmadık. Ben de çevik süreçler öldü diyorum, lakin ekliyorum: “yaşasın çevik süreçler”. Çevik süreçlerin yıldızlarının bundan sonra nasıl parlayacaklarını ve tam anlamıyla yazılım geliştirme süreçlerine hakim olacaklarını kendi yazılımcı perspektifimden sizinle paylaşmaya çalışacağım.

Bir yazılım sistemi belli bir büyüklüğe ulaştıktan sonra, kendi dinamiklerini oluşturarak, yeni özellikler eklenmek suretiyle geliştirilmesini engeller hale gelir. Bunun başlıca sebebi, mevcut mimarinin yeni özellikleri taşıyacak yapıda olmamasıdır. Bunu bilen yazılımcılar iki nokta arasındaki en kısa mesafeyi seçmek yerine, en az dirençle karşılacakları patikayı yeğlerler. Bunun neye sebebiyet verdiğini çok iyi biliyoruz: teknik borç! Burada yazılımcının büyük oranda suçu olmadığını düşünüyorum. Daha ziyade yazılımdan bihaber yöneticiler zaman baskısı oluşturarak, işi aceleye getirmektedirler ve aslında başarısızlığın temelini ilk saniyeden itibaren atmaktadırlar. Bu duruma yazılımcılar tepki vermeyerek ve kimsenin etlisine, sütlüsüne karışmayarak ortak olmaktadırlar. Lakin şöyle yöneticilerin karşılarında ağız birliği yaparak, dik durabilseler ve “madem bu işi biz yapıyoruz, o zaman ne zaman biteceğine de biz karar veririz” diyebilseler, çok daha güzel işler ortaya koyabilecekler.

Yazılımda bu sorun ile başa çıkmanın tek bir yolu mevcut, o da refactoring olarak adlandırılan kodun yeniden yapılandırılmasıdır. Teoride her yazılımcının yeniden yapılandırmanın ne anlama geldiğini bildiğini düşünebiliriz. Lakin pratik açıdan baktığımızda, yeniden yapılandırma işleminin nasıl yapıldığı konusuna çok az sayıda yazılımcı hakimdir. Bunun da başlıca sebebi, yazılım testleri üzerinde olan hakimiyetsizliktir.

Refactoring tek başına yapılması mümkün olmayan bir işlemdir. Yapılan her değişiklik bir yan etki doğurabileceğinden, bu etkinin tespit edilebilmesi zaruridir. Bu kontrolü bir yazılımcının elden yapması mümkün değildir. Bu sebepten dolayı burada bir otomasyon ihtiyacı doğmaktadır. İhtiyaç duyulan kapsama alanına sahip olduğumuzu farz ettiğimizde, otomatik çalışan testler refactoring esnasında oluşan tüm yan etkileri tespit etmeyi mümkün kılacaklardır. Özetleyecek olursak, aslında yazılım sisteminin sürekli gelişimi için ihtiyaç duyduklarımız yeniden yapılandırma, test yazılımı ve test otomasyonudur. İşte çevik süreçlerin temelini de bunlar oluşturmaktadır. Eğer sürekli müşteri gereksinimlerini koda dökebiliyor ve mevcut sistemi genişletebiliyorsanız, çeviksiniz! aksi tektirde yazılımcılık oynuyorsunuz!

Çevik süreçler bünyesinde yer alan çevik metotların ana amacı yazılımda sürdürülebilirliği hedefliyor olmalarıdır. Burada sürdürülebilirlik terimini teknik açıdan ele almamız gerekmektedir. Sürdürülebilirlik bir yönetici için başka, bir yazılımcı için daha başka, bir patron için çok daha başka bir anlam ifade etmektedir. Ama doğru olan yaklaşım hangisidir? Şüphesiz herkes kendince doğru yaklaşım içindedir, çünkü beklentiler değişiktir. Lakin tekrar altını çizerek sormak istiyorum, teknik olarak sürdürülebilirlik ne anlama gelmektedir? Bunun cevabını verebilmek için öncelikle işin müşteri kısmını incelememiz gerekiyor.

Bir yazılım sistemi müşteri gereksinimleri doğrultusunda şekillenir. Yazılımcı olarak nihai amacımız, müşteri gereksinimlerini tatmin edecek bir sistem oraya koymaktır. Bu yüzden doğal olarak müşteriye kulak vermemiz ve ne istediğini iyi anlamamız gerekmektedir. Lakin müşteri ne istediğini tam olarak bilmekte midir? Ne yazık ki bu sorunun cevabı hayıdır. Burada yazılımcı olarak bizim için iki sıkıntı oluşmaktadır. Birincisi nasıl bir sistem oluşturmamız gerektiği sorusudur, ikincisi bu sistemin mimarisinin nasıl olması gerektiğidir. Bu iki sorunun da cevabını düşünerek, bulmamız mümkün değildir. O yüzden bir an önce kolları sıvıyarak, müşteriye yarım yamalak dile getirdiği gereksinimleri için kısa bir zaman dilimi sonunda bir şeyler göstermemiz gerekmektedir ki müşteri ne istediğine dair fikir üretmeye başlayabilsin. Bu yüzden çevik süreçlerde bir ya da iki haftalık iterasyonlar sonunda müşteriye mutlaka tespit edilen miktardaki özelliğin çalışır durumda olduğu sistemler sunulur. Bu prototipler müşteriden alınan geribildirimler doğrultusunda onun kullanacağı ürün olana kadar geliştirilir. Lakin burada tekrar sürdürülebilirlik konusuna değinmemiz gerekmektedir. Teknik olarak bu nasıl sağlanabilir? Bunun iki yöntemi mevcuttur: Teknik borç ve teslimiyet ya da kararlılık ile uygulanan “yap/boz” mentalitesi.

Eğer bir bina yapımı söz konusu ise, atılması gereken temelin ve uygulanmak istenen mimarinin bilinmesi gerekmektedir. Bu değişmez iki parametre yapılan binanın kaderidir. Eğer inşaat mühendisleri ve mimarlar yazılım yapmaya başlasalardı, hiç zorluk çekmeden bu işe adapte olabilirlerdi, çünkü günümüzde de yazılım bir bina inşaatı gibi ele alınmaktadır. Durum böyle olduğu için yazılım projelerinin çok büyük bir kısmı belli bir zaman sonra çıkmaza girerek, hem yazılım sistemini oluşturanları hem de müşterisini zorda bırakmaktadırlar.

Tekrar teknik sürdürülebilirlik sorusuna geri dönelim. Teknik sürdürüleiblirliğin bedeli ne yazık ki ağırdır. Öncelikle yazılımla uğraşan herkesin bu bedeli maddi ve manevi olarak ödemeye hazır olması gerekmektedir. Maddi açıdan baktığımızda yöneticilerin sürdürülebilirliği sağlamak adına daha fazla zamana ihtiyaç duyulduğunu ve bunun maliyeti artıracağını anlamaları, manevi açıdan baktığımızda yazılım mühendislerinin işin çıkmaza girdiğinde radikal kararlar vererek, refactoring teknikleri yöntemleri ile mevcudiyeti yeniden şekillendirme iradesine sahip olmaları gerektiğini görmekteyiz.

Günümüzde yapılan yazılımı yirmi sene önceki şekli ile kıyasladığımızda, aslında kafalarda fazla bir şeylerin değişmediğini görebilmekteyiz. Çoğu yazılım projesi yirmi sene önceki kafa yapısı (mindset) ile uygulanmaktadır. Yirmi sene önce aktif olarak hayatımıza giren çevik metotlar ihtiyaç duyulan dönüşümü sağlayamadılar. Bunun nedeni ne olabilir? Çevik süreçler performans gösterebilmek için çok radikal değişimlere ihtiyaç duymaktadırlar. Bu programcıların çalışma tarzlarından başlayarak, firmanın sahip olduğu yazılım geliştirme kültürüne kadar uzanana bir alanı kapsamaktadır.

Çevik süreçler programcı perspektifinden bakıldığında test güdümlü yazılım gibi radikal bir metodun uygulanmasını talep etmektedir. Yazılım birimlerini test etme konusunda pek kafa yormamış ve bu konuda tecrübesi olmayan bir yazılımcıdan test yazarak, yazılıma devam etmesini istemek, bir cobol yazılımcısına bugünden yarına nesne tabanlı program yazdırmaya çalışmak gibi birşeydir. Nitekim ikibinli yılların başlarında görev başında olan yazılımcıların bu fikri benimsemeleri mümkün olmadı. Onlar hep testlerin yazılımın en sonunda uygulanan bir aktivite olarak gördüler. Her zaman angarya olarak görülmüş test yazma olayının birden bire gündemin en başına oturarak, tüm gidişata yön verme fikrine o jenerasyon ne yazık ki adapte olamadı. Tekrar hatırlamakta fayda görüyorum. çevik olabilmeniz için yani müşteri gereksinimlerine her daim yazılım ile karşılık verebilmeniz için yeniden yapılandırma yapmak zorundasınız. Test olmadan yeniden yapılandırma yapılamaz. Bu yüzden çevik süreçlerin en temelinde bu iki prensip yatmaktadır: yeniden yapılandırma ve testler. Olay sadece test güdümlü yazılım ile bitmiyordu. Eşli programlama, sürekli entegatasyon, iterasyon bazlı yazılım gibi birçok çevik süreç metodu mevcut yazılım süreçlerini yer yer tersine çevirdiğinden dolayı, bu durum yazılımcılara sudan çıkmış balık hissi yaşatmakta ve adaptasyonu zorlaştırmaktaydı.

O dönemin yazılım sektöründe çalışanlarını şelale (waterfall) yazılım süreçlerinden geldiklerini unutmamamız gerekmektedir. O zamanın yazılım ekipleri müşteri gereksinimlerini en ince detayına kadar anladıktan ve kağıda döktükten sonra yazılım yapmaya başlarlardı. Burada bir senelik bir ön çalışma ve akabında yine birkaç sene sürebilen yazılım geliştirme sürecinden bahetmekteyiz. O gün olsun, bugün olsun yazılım projelerinin başarısız olmalarının ana sebeplerinden birisi ne yazık ki budur. Müşteri gereksinimleri doğrultusunda bir yazılım sistemine ihiyaç duyar. Müşterinin bu gereksinimleri piyasa şartları ile günlük bazda bile değişime uğrayabilirken, şelale yöntemleri ile birkaç sene kapalı kapılar arkasında yapılan yazılımın, bu zaman dilimi sonunda müşteri gereksinimlerine ne kadar az hitap edebilme potansiyeline sahip olduğunu görebilmekteyiz. Nitekim yazılım projelerindeki başarısızlık, müşteri gereksinimlerinin ne oranda karşılık göremediği ile çok yakından bağlantılı.

Hala ikibinli yılların başlarındayız ve çevik süreçlerin var olma savaşını yakından inceliyoruz. Şimdi o zamanlar yazılımın nasıl yapıldığını ve uygulanan mimarileri yakından inceleyerek, çevik süreçlerin neden tutunamadığını görmeye devam edelim.

İkibinli yılların başlarında Java programlama dili sahip olduğu ekosistemi ile tüm yazılım camiasına hakim olmaya başladı. O zamanlar EJB (Enterprise Java Beans) ile uygulama sunucularında yazılım yapanlar çok iyi hatırlayacaklardır. Tarih hep tekerrürden ibarettir, lakin umarım o günleri hiçbir yazılımcı tekrar yaşamak zorunda kalmaz. O devrin yazılım yöntemleri, araç ve gereçleri çevik süreçler için hazır değildi. Siz ne kadar iyi niyetli de olsanız ve test güdümlü yazılım ile birim testleri yazsanız bile, entegrasyon, onay/kabul testleri ve benzeri testlerin otomatik çalıştırılmaları onlarca ya da yüzlerce dakikanızı almaktaydı. Çok küçük bir değişilik yaptığınızı düşünün. Uygulamanın tekrar paketlenerek, uygulama sunucusunda çalışır hale gelmesi en az on dakikanıza mal olmaktaydı. Bunu çok defa yaşamış bir programcıyım. Çeviklik geribildirimle doğrudan orantılıdır. Yaptığınız şey size ne kadar hızlı geribildirim sağlarsa, o hızda değişilik yapabilirsiniz. Çevik olabilmek için yeniden yapılandırmamız gerekiyor. Bunun için testlerin sağladığı geribildirime ihtiyacımız var. Aynı şekilde sürekli entagrasyon yaparak, sistemin hangi derecede entegre olduğu geribildirimine ihtiyaç duymaktayız. Tüm çevik metotlar geribildirim prensibine dayanmaktadır. Geribildirim sağlanmadan, yaptığımız işin neresinde olduğunu anlamamız mümkün değildir. Geribildirim alma süresinin uzaması, bu o oranda çeviklikten uzaklaşma anlamına gelmektedir. Nitekim uygulama sunucularından kaynaklanan sebeplerden dolayı çok zaman alan test otomasyonu ilerleyebilmek adına devre dışı bırakılmak zorunda kalındı. O devrin EJB projelerine göz attığımız taktirde ya hiç ya da çok çok az oranda test koduna sahip olduğunu görebiliriz. Aynı durum bugün yapılan projeler için bile geçerlidir. Birçok güncel projede bir tane bile test metodu bulunmaması hiç şaşırtıcı değildir. Projelerin neden sürdürülebilir olmadıklarını ortadadır.

İkibin onlara kadar uygulanan yazılım prensip ve mimarileri de ne yazık ki çevik süreçler için gerekli ortamı oluşturamadı. Bahsetmiş olduğum zaman diliminde monolitler revaçtaydı. Durumun bugün bile değişik olduğu söylenemez. Trendin ama microservice mimarileri ile değiştiğine şahit olmaktayız. Peki bir monolit çevik süreçler ile geliştirilemez anlamına mı gelmektedir bu? Bu monolitin büyüklüğü ve bünyesinde barındırdığı kod kalitesi ile doğrudan ilişkili bir durum.

Çevik süreçler ile bir monoliti geliştirmek mümkün. Ama bu ne yazık ki belli bir büyüklüğe kadar sağlanabilir. O kritik büyüklüğe erişildikten sonra, sistemin küçük ve birbirinden bağımsız parçalardan oluşuyor ve geliştirilebiliyor olması gerekmektedir. Yani burada modüler bir yapıya ihtiyaç duyulmaktadır. Lakin bir monolit ne kadar modüler bir yapıda da olsa, tek bir parça olarak entegre edilmesi gerekmektedir. Burada yine test otomasyonu sorunları baş göstermektedir. Bunun yanı sıra entegrasyon süreleri uzamakta ve hızlıca yapılması gereken değişiklikler zaman almakta ve çeviklikten ne yazık ki ödün verilmesi zazuri bir hale gelmektedir. Tekrar hatırlayalım: hızlı bir şekilde geribildirim alınamayan ortamlarda çevik olunması imkansızdır.

Çevik bir yazılım ürünü yani her yeni müşteri gereksnimi ile yeniden yapılandırılabilen ve sürekli değişiklik ile başedebilen bir yazılım sistemi için belli başlı yazılım prensiplerinin, tasarım şablonlarının ve yazılım mimarilerinin uygulanması zaruridir. En basit hali ile clean code, solid prensipleri ve modüler bir mimariye ihtiyaç duyulmaktadır. Bunların uygulandığı bir proje test kültürü ile birleştiğinde her yeni müşteri gereksnimi ile hamur gibi yoğrulabilen yazılım ürünleri ortaya çıkamaktadır. Ama günümüzde bile birçok projede test kodunu bir yana bırakın clean code ya da solid prensiplerinden eser bile bulmak mümkün değildir. Testler olmadığından dolayı programcılar artık binlerce satırdan oluşan sınıfları değiştirmeye korkar olmuşlardır. Bu korkunun mevcut olduğu bir yerde nasıl yeni müşteri gereksinimleri hayat bulabilir?

Teknik açıdan baktığımızda, birçok sebepten dolayı çevik süreçlerin uygulanabilir olmadıklarını ve bu yüzden bir zaman sonra terk edildiklerini görebilmekteyiz. Lakin bunu tümüyle teknik sorunlarla ilişkilendirmek doğru değildir. Bunun yanı sıra firmalarda oluşan yazılım geliştirme kültürlerini ve organizasyonel yapıları da yakından incelememiz gerekmektedir.

Zaman içinde, çevik süreçlerin popülerliğinden de istifade edilerek benim fake agile olarak tabir ettiğim ve yazılımda çevikliği ima eden ama bunu sağlamaktan çok uzak sözde çevik süreçler oluştu. Bunların başında scrum geliyor. Scrum yakından incelendiğinde, aslında yakından, uzaktan çeviklik ile hiçbir alakası olmayan bir şey olduğu görülmektedir. Scrum ne çeviklik namına bir çevik metot ihtiva etmektedir ne de scrum ile çevik bir yazılım ürünü geliştirmek mümkündür. Çevik olmak için çevik metotlara ihtiyaç duyulmaktadır. Bunlar teknik anlamda yazılımcılar tarafından uygulanan metotlardır. Test güdümlü yazılım ya da eşli programlama gibi çevik metotları sadece yazılımcılar uygulayabilirler. Tüm çevik metotlar yazılımcılar için ve onların çevik hareket edebilmeleri için oluşturulmuşlardır. O yüzden çevik süreçler yardımı ile yazılım yapıyoruz denildiğinde, incelenmesi gereken nokta, çevik metotların ne oranda yazılımcılar tarafından yaşanıyor olduklarıdır.

Scrum ve benzeri yapılar ne yazık ki extreme programming gibi gerçek çevik metotların önüne geçtiler ve organizasyonlara çevik oldukları hissini verdiler. Kendini iyi hissetmekten öteye götüremeyen bu yaklaşımlar yazılım yapanların “çevik çalışıyor olmamıza rağmen, gerekli performansı alamıyoruz” söylenimlerine yol açtılar. Scrum ve benzeri yapılar ne yazık ki gerçek çevik süreçlerin adlarını karaladılar ve diskredite olmalarına sebep oldular. Bugün baktığınızda çevik olmayan bir yazılım ekibi bulamazsınız. Herkes scrum yapıyor ve herkes çevik. Ama ortaya çıkan yazılım ürünlerine göz attığımızda, hepsinin aynı dertlere sahip olduklarını ve aslında müşteri gereksnimlerine cevap veremeyecek yapıda, teknik ve mimarı açıdan tükenmiş olduklarını görmekteyiz.

Çevik süreçlerin önünü kapatan diğer bir durumda, yazılım ekiplerinin organizasyon yapısı olmuştur. Klasik bir yazılım ekibinde yazılımcı, testçi, analizci, sürümcü, proje yöneticisi gibi rolleri görmek mümkündür. Bir fabrika bandında üretim için uygun olan bu rol bazlı kadrolaşma, yazılım için ne yazık ki büyük sorular doğurmaktadır. Çevik süreçler yazılım, test, analiz, sürüm ve canlı işletme sorumluluğunu (production) yazılım ekibini oluşturan yazılımcılarda görmektedir. Yazılımcılar yazılım ile ilgili her şeyi yapamazlar mantığı doğru değildir. Mühendislik altyapısına sahip bu kişilerin günümüzde sadece kod yazmak için uygun olduklarını düşünmek en kibar ifadeyle onlara yapılan haksızlıktır. Nitekim Google tarafından uygulanan SRE (Site Reliability Engineering) ve DevOps gibi akımlara baktığımızda, yazılım ekibinin yazılım için gerekli tüm işlevleri yerine getirdiklerini görmekteyiz. Yazılımın, testin, analizin ve sürümün ayrı ekipler tarafından yapıldığı ortamlarda, çevik süreç faydalı olamamaktadır. Bu tür ayrıştırıcı organizasyonel yapılar olduğu sürece, çevik yazılım yapmak ne yazık ki mümkün değildir.

Yazılımda teknik sürdürülebilirlik için gerekli etkenleri ele almaya çalıştım. İsmi illa çevik süreç olmak zorunda değil. Lakin sürdürülebilirlik için atılması gereken somut adımlar var. Yazılımcının ana görevi sadece kod yazmak değildir. Mevcut organizasyonel yapılar bunun doğru olduğu fikrini savunsalar da teknik sürdürülebilirlik için yazılımcılara daha fazla sorumluluk verilmesi gerekmektedir. Yeni gereksinimlerin ivedilikle yazılım ürününe entegre edilebilmeleri için kodun her daim hamur gibi yoğrulabilmesi gerektirmektedir. Bunu sadece ve sadece yazılımcılar yapabilirler. Bunun için yüksek seviyede teknik beceriye ihiyaç duyulmaktadır. Bu da mühendisliğin hakkını verebilen yazılımcılarla mümkün olabilecek bir iştir.

Buraya kadar bahsetmiş olduğum nedenlerden dolayı çevik süreçler ne yazık ki hak ettikleri yere gelemediler ve haksız yere işe yaramaz damgasını gördüler. Ama ben bu durumun değişme sürecine girdiği düşüncesindeyim. Çevik süreçlerin işlemesini engelleyen unsurların yavaş yavaş kaybolmaya başladıklarına şahit olduğumuz bir dönemden geçiyoruz. Bu unsurlardan bazılarını yakından inceleyelim.

Artık günümüzde monolitlerin terk edilmeye yüz tutmuş bir mamarı türü olduğunu görmekteyiz. Modern yazılım sistemleri küçük ve birbirlerinden bağımsız çalışan modüllerden oluşmakta. Bunu sağlamak için microservice, webservice, rest ve soa gibi mimariler ve kubernetes, docker ve cloud gibi altyapı ve teknolojiler tercih edilmekte. Belli bir büyüklüğü geçmeyen ve otonom çalışan kod birimlerinin bakımı, geliştirilmesi, test edilmesi, sürümlenmesi ve işletilmesi geçmişe nazaran çok daha kolay.

Günümüzde yazılım ekiplerinin yapıları da değişmeye başladı. Örneğin Google bünyeside SRE olarak bilinen takımlar, test etmeden işletime kadar uygulamanın her yönüyle ilgileniyorlar. Birçok yeni ekip iki pizza prensibine göre oluşturuluyor. İki pizza ile doymayan bir ekip, büyüklüğü itibari ile monolite dönebilecek yapılar oluşturma eğilimi gösterebilmektedir. Küçük ekip ve tek sorumluluk prensibi kolay değiştirilebilir ve geliştirilebilir yazılım birimleri için sihirli bir formül haline geldi.

Bunun yanı sıra yazılımcılar eskiye nazaran tasarım prenbipleri, tasarım şablonları ve yazılım mimarileri konularında daha donanımlı hale geldiler. Clean code, software craftşman ve devops akımları, yazılımcıların teknik olarak daha da iyi olmaları için gerekli fikir ve pratikleri ihtiva ediyorlar. Ayrıca günümüzde eskiye kıyasla yazılımda teknik sürdürülebilirliği destekleyici, sonar, jenkins, git gibi birçok açık kaynaklı ürün bulmak mümkün.

Müşteri cephesinde de bazı değişiklilerin meydana geldiğini görmekteyiz. Müşteri eskisi gibi artık yıllar sonra kullanmaya başlayacağı bir yazılım ürünü siparişi vermek istemiyor. Müşteri bugün siparişini verdiği yazılım ürününün ilk sürümünü birkaç hafta sonra kullanmaya başlamak isteyebiliyor. Buna sadece çevik süreç ve iterasyon bazlı çalışma ile cevap vermek mümkün. Ayrıca müşteri için bir yazılım ürününün kullanılabilirlik seviyesi de değişmiş durumda. Piyasa rekabetinden doğan yeni gereksinimlerinden dolayı müşteri yıllarca beklemek yerine, sürekli geliştirilen, gereksinimler doğrultusunda adapte edilen ve her daim kullanılabliir yazılım ürünlerine yönelebiliyor.

Yirmi sene öncesi çevik süreçler ve tdd, bdd, pair programming, ci, refaçtoring, solid gibi çevik metotlar uygulanmaya başlandığında devir monolitlerin hakim olduğu mimarı devirdi . Çevik süreç ile bir monolit geliştirmek sadece iyi bir niyetten öteye gidemedi ve bu yüzden çevik süreçlerin bir işe yaramadığı düşünüldü. Oysaki container ve microservice dünyası için çevik süreç biçilmiş bir kaftan. Yıldızı söndüğü zannedilen çevik süreçler bulut bilişim ile ne olduklarını ispatlayacaklar.


Not: Eğer extreme programming gibi safkan bir çevik sürecin nasıl işlediğini merak ediyorsanız, size pratik agile isimli ücresiz kitabımı tavsiye etmek isterim. Çevik süreçler hakkındaki yazılarıma buradan, buradan ve buradan ulaşabilirsiniz.


EOF (End Of Fun)
Özcan Acar

Çevikliğin Böylesi

Son zamanlarda yazılımla yakından ya da uzaktan ilişkisi olan herkesin ağzında olan kelime; çeviklikten bahsediyorum. İngilizce de agile, lean gibi kavramlar kullanılıyor ve artık her şey için kullanılmaya başlandı. Gören de zannederki artık her proje çevik yazılım yöntemleri ile yapılıyor, her şey yolunda.

2010 senesinde Londra’da yapılan Domain Driven Design exChange konferansında Eric Evans, yazılımda çevikliğin anlamının kaybolduğunu çünkü artık her şeyin çevik olarak isimlendirildiğini söylemişti. Ne kadar haklı. Aşağıdaki fotografı bir trende çektim. Artık iş verenler bile çevik kelimesini kullanarak yazılımcıları oltaya düşürmeye çalışıyor. Çevik bir fare, çevik bir klavye belki de çevik bulut (agile cloud) bile kullanıyorken bulabiliriz kendimizi yakında. Yaşasın hayatın her safhasında karşılaştığımız çeviklik.

Son günlerin en moda çevik terimlerinden birisi Scrum. Avrupa’da artık birçok proje Scrum ile yapılıyor. Proje yöneticileri Scrum’la oturuyor, Scrum’la kalkıyor. Scrum yazılımda yeni bir dönemin başlangıcı. Diğer çevik süreçler on, on beş yıldır piyasada olmalarına rağmen, Scrum iyi pazarlandığı için çeviklik deyince ilk akla gelen süreç oluyor. Şahsen Scrum yöntemleri beni elektrik gibi çarpmamış olsa bile (çok fazla etkilenmediğim anlamında), Scrum doğru uygulandığında bir projede çevikliğin başlangıcı olabilir. Bugüne kadar birçok Scrum projesinde çalıştım ve doğru düzgün uygulandığını görmedim. Eski proje yöneticileri şimdilerde Scrum Master olmuşlar ve eski yöntemleri ile projeleri sürdürmeye devam ediyorlar. Kafalarda değişen fazla bir şey olmamış. Scrum’ı elbise olarak almışlar, kendi bedenlerine uydurmaya çalışmışlar. Bu bir yere kadar doğru olabilir, ama daha doğrusu Scrum elbisesini alıp, bedeni ona göre uydurmaktır. Scrum harfiyen ne istiyorsa proje ve çalışmalar ona göre şekillendirilmelidir. Ama mevcut kafalar değişmedikçe Scrum ve diğer çevik süreçlerin başarılı olmaları mümkün değil. Çeviklik, eski kafaların eski yöntemlerle yaptıkları işleri kendi yöneticilerine satmak için kullandıkları bir kavram haline geldi. Scrum projelerinde edindiğim tecrübeleri size aktararak çevikliğin nasıl yarı yolda kaldığını ve gerçek çevikliğin ne anlama geldiğini aktarmaya çalışayım.

Katıldığım ilk Scrum projesini hatırlıyorum. Sıkı bir mülakatın ardından projeye alındım. Mülakat esnasında bana bir sürü Java bulmacası soruldu. Maksat ne kadar derin Java bilgisine sahip olduğunu anlamaktı. Ama test güdümlü yazılım ya da JUnit hakkında bir kelime bile edilmedi. Aynı tarzda mülakatlar ile başka programcılar da projeye dahil edildi. Onlarda da durum farkli değildi. Ben programlarımı test güdümlü yazmaya gayret gösterdim. Ama bazı programcılar kırık kodları versiyon kontrol sistemine ekledikleri için testlerim çoğu zaman çalışmıyordu. Bu beni çok rahatsız eden bir durumdu. Test yazmaya önem vermeyen bu tür programcılarla çok ağız dalaşımız oldu. Sürekli entegrasyon serveri kullanılmıyordu, test güdümlü çalışılmıyordu, müşteri gereksinimleri kullanıcı hikayeleri olarak hazırlanmamıştı. Hangi kullanıcı hikayesini ne kadar zaman diliminde tamamlarız diye tahmin etme oturumları yapılmıyordu. Ama bir Scrum ekibi ve projesiydik. Her sabah on beş dakika asker gibi sıraya girip, Scrum toplantımızı yapardık. Bunun neresi çeviklik, neresi Scrum. Günde on beş dakika toplantı yaparak çevik olunmaz! Zaman kaybından başka bir şey değildir, göz boyamacadır.

Çalıştığım diğer bir Scrum projesinde Scrum’ın doğru adapte edilmesi için gayret gösterilmişti. Bir sürekli entegrasyon serveri ve yazılım metriklerini takip etmek için Sonar sunucusu kullanıyorduk. Zaman yetersizliğinden dolayı programcılar test yazmaya önem vermıyorlardı. Ayrıca uygulama bir uygulama sunucusu içinde çalışmak zorunda olduğu için test yazmak kolay değildi. Mevcut testlerin hepsi entegrasyon testi tarzındaydı. En ufak bir değişiklikte bile yeniden bir EAR paketi oluşturup, tüm uygulamayı uygulama sunucusuna çekmek gerekiyordu. Uygulama sunucusunun ayağa kalkması beş dakika sürüyordu. Yazılım geliştirme tamamen uygulama sunucusu ile iç içe geçmiş durumdaydı. Uygulama sunucusunu kullanmadan yazilim yapmak mümkün değildi. Test eksikliğinden ve uygulamanın bir uygulama sunucusuna çekilmesi gerektiğinden, uygulamayı yeniden yapılandırmak çok zordu. Uygulamayı uygulama sunucusundan bağımsız bir hale getirmek için çaba sarfetmemiz gerektiği konusunda çok dil dökmeme rağmen bu gerçekleşmedi. Sonuç olarak çevik değildik, çevik olamadık. Her yeni bir ekleme ile uygulamayı değiştirmek daha da zora girdi. Eğer programcılar ölmedilerse hala yaşıyorlar.

Çevik Nasıl Olunur?

Çevik olmak öncelikle cesaret ister. Gelenekleri bir kenara itip, yeniden başlamayı gerektirir. Felç geçirmiş bir insanın yeniden konuşmayı ya da yürümeyi öğrenmesi gibi çeviklikte her şeyi unutup, yeniden öğrenmeyi gerektirir. Çevik olmayı zor kılan da budur. İnsanlar alışkanlıklarından kolay kolay vaz geçemezler. Radikal değişimleri sevmezler. Yeniliklere kolay kolay adapte olamazlar. Dünya yerinde dursun isterler. Ama yazılım yapmak gibi dinamik bir ortamda değişmeyen tek şey değişikliğin kendisidir. Bununla yaşamak her babayiğidin harcı değildir. Cesur olanların, yeniliklere açık olanların işidir. Buraya kadar olan çevikliğin edebi tanımıydı. Şimdi gelelim teknik tanımlamasına.

Çevik olmayı ben hamur yoğurma ile kıyaslarım. Hamuru, içinde yeterince sıvı olduğu sürece yoğurabilirsiniz. Sıvı azaldıkça hamuru yoğurmak zorlaşır. İçinde sıvı kalmamış hamuru yoğuramassınız. Bu analogiden yola çıkarak çevikliğin yazılımdakı tanımlamasını yapalım. Hamur oluşturduğumuz yazılım sistemi, sıvı birim testleri, yoğurma ise yeniden yapılandırmadır (refactoring). Birim testleri olmadan yazılım sistemini yoğuramassınız (yeniden yapılandıramassınız), ama her yeni müşteri gereksinimi ile sizden yazılım sistemini yoğurmanız beklenir. Oluşturduğunuz uygulamaya yeni müşteri gereksinimlerini eklemek, yani uygulamayı yoğurmak zorundasınız. Bu işi yapmak yani programcı olarak çalışmak istiyorsanız başka alternatifiniz yok. Patronunuz ve müşteriniz sizden uygulamayı yoğurmanızı yanı kendi isteklerine cevap verecek şekilde geliştirilmenizi bekler. Birim, entegrasyon ya da onay/kabul testleri yazmıyorsanız uygulamayı yoğururken sıvı buharlaşacak ve siz belli bir noktadan itibaren uygulamayı yoğuramama rizikosuyla karşı karşıya kalacaksınız. Ama sizden yoğurmaya devam etmeniz beklenecektir. Birçok proje ya da geliştirilen uygulama bu sebepten dolayı başarısız olmaktadır. Devam etmek istiyorsanız uygulamaya sıvı katmanız gerekir. Oluşturacağınız yeni testler hamurunuz için yeni sıvı olacaktır. Bu testler hamuru tekrar yumuşatır ve yoğrulmasını kolaylaştırır. Programcı testleri kullanarak uygulamayı yeniden yapılandırabilir (refactoring). Bu hamuru yeniden yoğurabilme yeteneğini kazanmak demektir. Testler yoksa yeniden yapılandıramaz. Yeniden yapılandıramassa uygulama sıvı eksikliğinden katılaşır ve yoğrulamaz hale gelir. Çevikliğin ve esnekliğin gizli anahtarları testler ve yeniden yapılandırmadır. Bu iki anahtarı kullanmayı bilen programcı çeviktir. Tüm çevik olma hevesinin temelinde bu iki element yatar. Bu iki elementin olmadığı yerde çeviklik olamaz. Uygulamayı istekler doğrultusunda yoğuramadıktan sonra ne proje yönetiminin, ne Scrum’ın ne de çok iyi programcılardan oluşan ekibin bir anlamı kalır. Proje yöneticisi istediği kadar tavana zıplasın; katılaşmış bir uygulayı yeni kod yazarak yumuşatamayız, sadece test yazarak ve devamlı refactoring yaparak bu amaca ulaşabiliriz. Yazılımda işin özü budur: hamuru devamlı yoğrulacak kıvamda tutmak. Hamuru yoğurabilmek demek müşteri gereksinimlerine cevap verebilmek demektir, yani anında görüntü. Anında görüntüyü katılaşmış bir hamurla, yani yazılım sistemi ile yapamayız. Çıkarılması gereken sonuç çok basit aslında: sadece çevik süreç uygulayan projeler yoğrulabilir hamur üretir ve müşterinin yeni gereksinimlerine cevap verebilir.

Çevik olabilmek için çevik yazılım metotlarına hakim olmak gerekir. Her sabah on beş dakika toplantı yaparak elde edilebilecek bir durum değildir bu. Çevikliği anlayanlarla, anlamayanlar arasındaki fark budur. Çevikliği anlamayanlar çeviklik buzulunun (eisberg) su üstündeki kısmını görürler. Su üstünde görünen kısım, su altında kalan kısımdan çok küçüktür. Asıl çeviklikle haşır, neşir olma su altında olur. Her şeye Scrum, lean, agile diye isim verenler su üstünde yaşarlar, suyun altında olup bitenlerden bihaberdirler, çünkü derine dalmaya korkarlar. Onlar değişikliği zaten sevmezler. Eski çalışma tarzlarına çeviklik etiketini yapıştırıp hayatlarına devam ederler. Çeviğiz diye kendilerini ve etraflarındaki insanları kandırırlar. Hamuru yoğururken sıvı tükenmeye yakın panik olurlar. Ne yapacaklarını şaşırırlar, neden böyle oldu diye kara kara düşünürler. Çevik olduklarına kendileri de o kadar inanmıştir ki, suçu çeviklikte bulurlar. Çevikliği sevmemeye başlarlar. Onlar için suçlu olan çevik olma paradigmasıdır. Bilmezler ki çevikliğin hakkını verememişlerdir, çünkü ne olduğunu tam olarak kavrayamamışlardır. Değişikliğe açık olmadıkları için kavramaları da kolay değildir.

Gelelim çevik olmayı anlayanlara. Onlar bahsettiğim iki anahtarın sahibidir. Test güdümlü kod yazmayı bilirler ve her fırsatta bunu uygularlar. Bunun yanısıra refactoring konusunda uzmandırlar. Her yeni müşteri gereksimi ile daha önce verdikleri tasarım kararlarını revide ederler. Uygulamanın katılaşmaya başladığında mevcut tasarımın yetersiz olduğunu anlarlar ve bu tasarımı bozup, yeni bir tasarım yapmaktan çekinmezler. Cesurdurlar. Bilirler ki ellerindeki testler yeniden yapılandırma işlemini mümkün kılar. Buradan çıkardığımız ilk sonuç şudur: çevik olabilmek için test güdümlü yazılım yapmak önem taşımaktadır. Test güdümlü yazılım yapılamıyorsa, o zaman uygulamanın büyük bir kısmını kapsayacak şekilde test kodu yazılmalıdır. Oluşturulan testlerin otomatik olarak çalışması gerekmektedir. Yeniden yapılandırma (refactoring) işlemlerinin birçok yan etkisi olabilir. Onları hızlı bir şekilde lokalize edebilmek için otomatik çalışan testlere ihtiyaç duyulmaktadır. Testlerin olmadıği ya da yetersiz olduğu projelerde programcılar yeniden yapılandırma işlemine cesaret edemezler. Cesaret edemedikleri için yazılım sistemi her gün biraz daha katılaşır ve bir zaman sonra yoğrulamaz hale gelir. Eğlencenin bittiği an budur. Bu noktadan itibaren programcılar için cehennem azabı başlar. Fazla mesailer yapılır, beraber ağıtlar yakılır, kollektif çığlıklar atılır, sende mi Brütüs, sana o kadar emek verdik, yaptıkların bize caiz mi diye yazılım sistemine yüklenilir. Ama Brütüs suçsuzdur. O beni yoğurmayın dememiştir ki. Yoğurma cesaretini programcılar gösterememiştir.

Gerçek çevikliğin temelinde gerçek yazılım mühendisliği metotları yatar. Birincisi test güdümlü yazılım; ikincisi yeniden yapılandırma (refactoring); üçüncüsü eşli programlama; dördüncüsü sürekli entegrasyon; beşincisi basit tasarım; altıncısı iteratif sürüm oluşturma; yedincisi ….

Bu metotların hepsi insanların bilgisayarları icadı ve program yazmaları ile birlikte yer yer uygulanmış metotlardır. Hiç biri yeni icat edilmemiştir Ama bundan on, on beş sene önce Extreme Programming (XP) olarak topluca karşımıza çıktılar. XP bünyesinde proje yönetimi için de metotlar barındırmaktadır. XP bu metotları Scrum’dan almıştır. Ama Scrum bünyesinde XP’nin sahip olduğu çevik metotlar yoktur. Bu yüzden içinde çalıştığım hemen hemen her Scrum projesi sadece kağıt üzerinde çevik olabilmiştir. Saha’ya inildiğinde çevikliğin bir tane atomuna bile rastlamak mümkün olmamıştır.

Sadece proje yönetmek ve programcıların ne yaptığını kontrol etmek için icat edilmiş sözde çevik süreçleri kullananlara sesleniyorum buradan. Gerçek çevik yazılım metotlarını kullanmadığınız sürece çevik olmanız bir hayal olarak kalacaktır. Bu yüzden sürdürdüğünüz birçok proje 130 km/h ile duvara tosluyor. Cesaret edip işin temeline inmeniz gerekiyor. Daha fazla mühendis olup, çevik metotlara hakim olmanız gerekiyor. Her gün on beş dakikalık toplantılarınızdan vaz geçin demiyorum. Bu yerinde bir aktivite. Ama zaman ayırıp bir mühendis kafasıyla sistematik olarak çevik yazılım metotları ile ilgilenin, onları öğrenin, onlara hakim olun, onlari uygulayın. Her Scrum projesini testlerin yine en son safhada yazıldığı ya da zaman yetersizliğinden dolayı yazılamadığı bir ortama çevirmeyin. Profilime ben de kulağa hoş gelen Scrum Master ünvanını koyarım. Ama bu benim ne kadar çevik metotlara hakim olduğumu yansıtmaz. Ünvanlardan çok, hakim olduğunuz gerçek çevik yazılım metotları ile övünün. Hamuru yoğuran ünvan değildir. Hamuru yoguran tecrübeli beyin ve sistemli ve sonuç getiren metotlar kullanmaya alışmış ellerdir. Gerçek yazılım mühendisleri ile düzmece mühendislerin arasındaki fark işte budur. Parayla satın alınan sertifikalar programcıyı programcı yapmaz. Bu sevdadan vazgeçin. Bu sözde çevik yöntemlerle ne dünyayı kurtarırsınız ne de yazılım dünyasına artı bir değer katarsınız.

Çekirdekte gerçek meselenin uygumalayı devamlı yoğurmak olduğunu göz ardı eden bu sözde çevik yöntemler, çevik teriminin her halt için kullanılması ve enflasyona uğramış olması, çevikliğin içinden çıkılamaz bir hale gelmesine sebep olmuştur. Kafalar iyice karışmıştır. Hangi yöntem çeviktir, nasıl çevik olunur, bu sorulara artık kimse net olarak cevap verememektir. Çeviklik artık ifade gücünü yitirmiştir. Bu gerçekten üzücü bir durum. Bir nevi komplo. Sanki eski şelale (waterfall) yöntemleriyle büyümüş bir zümre çevikliği ortadan kaldırmak için iş birliği içindedir. Böyle birsey yok doğal olarak. Fantazim yine kanatlandı.

Beni bir Scrum düşmanı olarak görmeyin. Doğru uygulandığında iyi bir başlangıç olabilir. Ne yazik ki Scrum’ın doğasından kaynaklanan bir sorun bu; Scrum’ı doğru uygulamak hemen hemen imkansız; her türlü uygulama tarzına açık; somut değil; isteyen istediği tarafa çekiyor, bu yüzden ortaya çok komik görüntüler çıkıyor. Scrum doğru uygulandığı taktirde ve proje bünyesinde XP vari yazılım metotları kullanıldığında bir proje tam anlamıyla çevik olabilir. Onun haricinde bu imkansız.

Çeviklikte her şeyin başı çevik mühendislik metotlarıdır. Bunun başında test güdümlü yazılım ve refactoring gelir. İçinde bu elementleri barındırmayan bir süreç çevik yazılım süreci olamaz. Para basmak ve dandik sertifikalar dağıtmak için oluşturulmuş sözde çevik süreçlerden uzak durmakta fayda var. Cesaret gösterip işin özüne inelim. Yeniliklere açık olalım. Yazılım mühendisi isek o zaman bir mühendis gibi çalışalım, sistemli ve metotlu. Buna izin verilmediği yerde durmayalım, baş kaldıralım. Yazılımda çeviklik sadece çevikliği kavramış mühendislerle mümkündür. Eski kafa bir proje yöneticisini Scrum Master yaparak proje çevikleştirilemez. Projede çevikliği yazılım mühendisleri ateşler, meşaleyi onlar ileri götürür, Scrum Master olmuş birisi değil. Onlar en fazla seyirci olabilirler. Sahada maçı oynayan çevik yazılım mühendisleridir. Çeviklik konusunda bunun harici her şey hikayedir.


EOF (End Of Fun)
Özcan Acar