Yazılımı Sıfırdan Yeniden Yazmak İle İlgili Kendime Notlar
Bir sistemi sıfırdan yeniden yazmak, bir tasarımcı olarak başarısızlığın kabulüdür.”Sürdürülebilir ve yönetilebilir bir sistem tasarlayamadık ve bu yüzden baştan başlamak zorundayız” gerçeği ile yüzleşmektir. — Max Kanat-Alexander, Code Simplicity
Diğer yazılım tasarımcıları ve mühendisleri gibi bende meslek hayatım boyunca bir kaç kez yazılımı yeniden yazma sürecinde görev aldım. Ve bu görevlere baktığım zaman çoğunda yanlış tasarlanan yazılım mimarisinin bu kararı verme de büyük rol oynadığını gördüm. Bu kararı vermede rol oynayan bir diğer etken ise yazılımın hayat seyri boyunca doğru bir şekilde yönetilememesi. Günü kurtarmak için verilen kararlar, hızlıca düşünmeden yapılan bug fixler, müşteriden gelen her bir isteğin düşünülmeden kodlanması vs. bir çok yanlış kararın yazılımcıları bu kararı almaya zorladığını gördüm.
Bu süreçte edindiğim birçok tecrübem oldu. Bu tecrübelerimi hem tarihe bir not düşmek hem de bu süreç öğrendiğim dersleri diğer yazılımcılarla paylaşmak için bu makaleyi yazmak istedim.
Başlayalım…
Çoğu durumda yazılımı sıfırdan baştan yazmak bir çözüm değil, yazılımcı yanılgısıdır
Yazdığın kod ile başın belaya girdiğinde, sorunun tam olarak ne olduğunu teşhis etmek önemlidir. Her geliştiricinin yapacağı gibi, ilk düşüncen kodu sıfırdan yeniden yazmak olmamalıdır. Çoğu durumda bu sadece bir yanılgıdır. Bu bir yanılgıdır çünkü başkasının yazdığı veya uzun zaman önce yazdığın kodu okumakta zorlanıyorsun ve sıfırdan yeniden yazarsan daha iyi bir iş çıkaracağını düşünüyorsun. Bu durumda, her zaman programlamanın temel yasalarından birini hatırla.
Kodu okumak yazmaktan çok daha zordur.
Kodu yeniden yazma sürecine ilk adımı atmadan önce kodu düzenlemeyi (refactoring) göz önünde bulundur
Belli kod bölümlerini hedef alan yeniden yazmalar kod tabanınızdaki en kötü sorunlarla başa çıkmak için yararlıdır. Eğer sorunun kapsamını ve tam olarak nereden kaynaklandığını limitleyebiliyorsan tüm yazılımı sıfırdan baştan yazmamalısın. Örneğin, yazılımın ilk açılırken ki yüklenmesinin çok yavaş olduğunu varsayalım. Böyle bir durumda bu sorun genellikle projenin çok küçük bir bölümünü etkiler. Bu tip problemler adım adım ilerleyip, yeniden kod düzenlemeleri, belli kodları taşımak ve bir takım arayüz değişiklikleri ile kolayca çözülebilir. Tüm projeyi yeniden yazmak zorunda değilsin.
Dikkat et! Yeniden yazma süreci, beklediğinden daha uzun, daha zor, hataya açık bir yoldur
Yazılım geliştiricilerinin genellikle son teslim tarihlerini kaçırdıktan sonra farkına vardıkları önemli bir gerçek vardır:
Herşey düşündüğünüzden daha çok zaman alır.
Eğer yazılımı sıfırdan yeniden yazmaya karar verdiysen, yeniden yazmanın sana mal olacağı zaman tahmini konusunda son derece kötümser ol. Yeniden yazma süreçleri daima düşündüğünden çok daha fazla zamana ve kaynağa mal olur. Süreç boyunca yeniden yazma sürecini daha çok zorlaştırıp, daha sancılı hale getirecek ve daima uğraşmak zorunda olacağın birçok karmaşıklık ortaya çıkacak. Bunların sonucunda başarısızlık yüksek ihtimaldir. Başarısızlık derken planladığın zamandan çok daha fazla zaman harcamak zorunda kalabilirsin.
Yeniden yazma sonucunda ortaya çıkan ürünün kullanıcıların sorununu çözmede eski üründen daha iyi (veya en azından aynı seviyede) olduğundan emin ol
Yeniden yazma sürecinin müşterilere direk olarak bir yararı veya etkisi yoktur. Kullanıcıların senin kodun hakkında zerre kadar bir fikri yoktur ve bunu umursamazlar. Onlar sadece yazılımla kendi problemlerini çözmek isterler. Hepsi bu kadar. Eğer yazılımın onların problemini çözme konusunda iyi ise kullanıcılar gözünde sen başarılısın. Aksi halde senin yazılımını kullanmayıp rakip yazılıma geçiş onlar için çok kolay bir işlemdir. Senin kodu yeniden yazma sürecinle ilgilenmezler bu yüzden yeniden yazılan yazılım en az eski yazılım kadar verimli çalışmalıdır.
Yeniden yazma süreci boyunca eski yazılımın bakımını yapmaya ve onu desteklemeye devam et
Dahil olduğum bir yeniden yazma sürecinden, 1 yıl boyunca eski yazılıma herhangi bir güncelleme vermedik. Günümüz dünyasında bu çok uzun bir zaman. Onca kötü koda rağmen yazılım hala kullanıcıların problemini çözmede iyi iş çıkarıyordu fakat kullanıcılar aylardır gelmeyen güncellemeler konusunda sürekli şikayet ediyorlardı.
Kullanımda olan mevcut ürünün bakımını yapmayı ve güncelleme vermeyi asla ihmal etme. Yeniden yazma süreci boyunca, eski kodun hala bakıma ihtiyacı vardır. Programcıların bir kısmı yazılımı yeniden yazarken, bir kısmı da eski yazılımla ilgili küçük güncellemeleri ve bug fixleri kullanıcılara vermek ile ilgilenmelidir. Aksi halde kullanıcıları kaybetmek tehlikesi ile karşı karşıya kalacaksın.
Kullanıcıları yazılımın tasarım sürecine mümkün olduğunca çabuk dahil et
Kullanıcılara şuandaki ilerleme ile ilgili düzenli aralıklarla bilgilendirmeler yap. Böylelikle kullanıcılar senin daha işin başındayken göremediğin sorunları görmene yardımcı olabilirler. Kullanıcılarınla mümkün olan en hızlı sürede buluşman önemli. Onların ihtiyaçlarına göre geri bildirimleri yeni ürünün tasarımında sana yardımcı olacaktır. Gereksiz yeni özellikler kodlamaktan uzak dur. Bu senin karmaşık bir kod tabanına sahip olmana engel olacaktır.
Ürün üzerinde çalışan takımların senkronize olduklarından emin ol
Bir ürün sadece yazılım ekibiyle ilgili değildir. Pazarlama, destek, yazılım, tasarım… Bir çok takım aynı ürün üzerinde çalışır. Düzenli bilgilendirmeler vererek yeniden yazma süreci ile ilgili ekipleri senkronize et.
Daha önce dahil olduğum yeniden yazma süreçlerinin bir tanesinde ekiplerin senkronize olmamasından dolayı bir çok problemle karşı karşıya kalmıştık. Örneğin, pazarlama ekibi yeniden yazılan ürünün beta sürecini hazırlıyordu ve yazılım ekibinin yeniden yazma sürecinde hangi aşamada olduklarını bilmeleri müşterilere doğru mesajları vermek için önemliydi. Bazen yazılım ekibi diğer ekiplerin bilgisi dışında bir takım değişiklikler yapıyordu. Pazarlama ekibinin bu değişikliklerden haberinin olmaması, hazırladıkları kampanyayı bir kaç kez baştan tasarlamak zorunda kalmalarına neden olmuştu. Ekipleri senkron tutarak, her birinin zamanlarını verimsiz bir şekilde harcamalarına izin verme.
Üründe büyük önemli değişiklikler yapma
Ürünün zayıf ve güçlü yönlerini bilmek önemlidir. Kullanıcıların sevdiği güçlü yönleri değiştirme. Örneğin, eğer kullanıcılar ürünün arayüzünü seviyorlar ise yeniden yazma sürecinde arayüzü değiştirme. Çok küçük değişiklikler ve kullanıcı deneyimi iyileştirmeleri yap. Eski ürünü yeni yazılan ürün ile değiştirdiğin zaman kullanıcıların yapılan dramatik değişiklikler yüzünden kafaları karışmamalı. Yeni ürünün önceki ürünün sağladığı fonksiyonelliği sağlayamadığından dolayı kullanıcıların ürünü terkettikleri bir çok hikaye var. Aynı senaryonun senin başına gelmesine izin verme.
Ürünün sadece bir yazılımcıya bağımlı hale gelmesine izin verme
Benim dahil olduğum bir süreçte, ana yazılımcılardan bir tanesi yazılımın büyük bir bölümünden sorumluydu. Aynı zamanda şirkette yönetimle ilgili işleri de bulunuyordu. Bulunduğu pozisyondan dolayı, ürün geliştirmesi sürekli yavaşlayıp gecikiyordu. Küçük değişiklikler bile haftalar alıyor hatta bazen aylar alıyordu. Yazılımdaki kısıtları bul ve onları ortadan kaldır. İlerlemeye devam et. Asla durma.
Eski yazılımdan yeni yazılıma geçiş yavaş ve istikrarlı olmalıdır
Yeniden yazılan yazılımın orjinal eski yazılımla değiştirilebilir olduğundan emin ol. Geçiş işlemini adım adım yap.
İlk olarak, küçük bir beta grubu ile ise başla ve ilk versiyonu bu küçük gruba ver. Devamlı olarak kullanıcılardan geri bildirimler ve hata raporları topla. Bugları fixle, küçük iyileştirmeler yap ve tekrar versiyon ver. Aynı işlemi tekrar tekrar yap. Bu süreci ürünün artık küçük beta grubundan çıkıp daha geniş bir beta grubuna dağıtıma hazır hale geldiğinden emin olana kadar tekrarla.
Daha geniş bir beta grubuna ürünü yaygınlaştırdıktan sonra, geri bildirimler yine senin en iyi dostun olacak. Bu aşamada ilk hedef ürünün kullanıcıların problemini iyi bir şekilde çözdüğündan emin olmaktır. Yeni ürünün kullanıcıların sorununu çözmede en az eski ürün kadar iyi veya daha iyi olduğundan emin olunca, artık ürünlerin değişim sürecini başlatabilirsin. Yeni kullanıcılar için yeni yazılımı vermeye başla. Mevcut kullanıcılar için de küçük gruplarla adım adım ilerleyerek yeni ürünün dağıtımına devam et. Bu süreçte geri bildirimlerin düzenli takipçisi ol ve kritik hataların olup olmadığından emin ol.
Bu sürece kadar anlattıklarım dahil olduğum yeniden yazma süreçlerinden öğrendiğim derslerdi. Bir yazılımı sıfırdan yazmak asla bir cevap değildir. Çoğu zaman, kodu yeniden düzenleme (refactoring) oynanacak en iyi bahis olarak görülmelidir. Benim önerim yavaş ilerlemelerle gerçekleştirilecek kodu yeniden düzenlemektir. Bana göre bu daha az riskli bir yol ve bu şekilde müşterilerin mutluluğunun devam etmesini sağlayabiliriz.
Kod ne zaman yeniden yazılmalı?
Yeniden yazmak çoğu durumda çözüm olmadığı gibi bazen yeniden yazma süreci kaçınılmaz olabilir. Bu durumları tecrübeme göre şöyle özetleyebiliriz.
Başka bir programlama diline veya platforma geçiş
Yazılımı geliştirdiğin programlama dili artık çok eskimiştir. Bu platformda ve programlama dilinde yazılımcı bulmak zorlaşmış ve başa çıkamayacağın büyük ücretler ortaya çıkmaya başlamıştır. Bu durumlar çok büyük çaba gerektiren durumlardır ve daha güncel bir programlama dili ile daha güncel bir platforma geçiş için yeniden yazma göze alınabilir.
Mevcut kod tabanının artık yönetilemediği durumlarda
Kodun yönetilemediğine nasıl karar verirsin?
Bunu belirlemek çoğu durumda çok zordur fakat şöyle bir yöntemle doğru cevaba ulaşılabilir:
- Küçük değişikliklerin yapılması bile artık çok zorsa
- Yeni güncellemeler olması gerektiğinden çok daha fazla uzun zaman alıyorsa
- Kod tabanında yapılan küçük değişiklikler diğer kısımları etkileyip ortaya yeni bugların çıkmasına neden oluyorsa yazılımınız artık yönetilemeyenler kategorisindedir diyebilirz.
Sahip olunan kaynaklar (odak, zaman, para) yazılımı yeniden yazmaya ve mevcut olana destek verip bakımını yapmaya yeterli ise
Kullanımda olan mevcut sistemin bakımını yapmayı ve desteklemeyi asla durdurmalısın. Eğer bir sistem kullanımdaysa her zaman yönetilmeye devam edilmelidir. Şunu unutma ki senin kişisel odağın burada saydığımız kaynaklardan bir tanesidir. Eğer hem yeniden yazma sürecinde hem de mevcut olana destek vermede yeteri kadar enerjin ve zamanın varsa tamam, hadi başla!
Yazılımda dar boğaz oluşturan yazılım geliştiriciler varsa
Bu tek başına yazılımı sıfırdan yeniden yazma kararını vermek için geçerli bir sebep değildir. Yazılım ekibinde dar boğaz oluşturanları değiştirebilir hatta ekibe yeni yazılım geliştiriciler dahil edebilirsin.
Ancak bazen, dar boğaz yüzünden yeniden yazma kararını alabilirsin. Yazılım eski bir teknoloji ile yazılmıştır ve en önemli ana yazılım geliştiricilerinden biri bu yazılımı geliştirmek için sorumlu olan teki kişidir. Genelde böyle eski teknolojiler için yazılım geliştirici bulmak çok maliyetli ve zor bir süreci içerir. O yüzden seni burada uyarıyorum. Dışarıdan kolaymış gibi görünse de bu beklediğinden çok daha fazla zaman alabilir. Bu projede çalışacak bir yazılım geliştirici bulsan bile maliyeti karşılayamayacağın boyutlarda olabilir. O yüzden yeniden yazma kararı aklının köşesinde bir yerde her zaman bulunmalı.
Yazılım artık yaşayan bir dinazor haline gelmiştir (10–20 senelik bir yazılımdan bahsediyorum)
Bakım zaman geçtikçe çok daha fazla maliyetli olmaya başlar. Bunun nedeni, yazılım mimarisinin çabuk bug fixler ve yamalarla hızlı bir şekilde spagetti haline gelen kodlar yüzünden feda edilmesinden dolayıdır. Ayrıca, eski teknolojileri geliştiren yazılım geliştiricilerin maliyeti artar ve bulunması zorlaşır. Sonunda, yazılımın üzerinde çalıştığı donanımlar yaşlanır ve yeni donanımlar, işletim sistemleri ve frameworkler gibi bileşenleri bulmak gittikçe zorlaşmaya başlar. Ek olarak şirketin sürdürdüğü iş günden güne gelişir ve yüksek ihtimalle eski sistem organizasyonun ihtiyaçlarına artık cevap verememeye başlar.
Bu gibi nedenlerle, devam eden tüm bakım maliyetlerinin yanı sıra yeni bir sistemin potansiyel faydalarını sıfırdan yeniden yazmanın maliyetine karşı tartmaya başlayarak uygun kararı verebilirsin.
Eğer senin durumunda yukarıda saydığım durumlardan herhangi birine uyuyorsa, yazılımı sıfırdan yeniden yazma kararı senin için uygun olabilir. Aksi halde, yapılacak doğru şey, sistemin tasarımını bir dizi basit adımla yeniden düzenleyerek; mevcut sistemin karmaşıklığını tüm sistemi yeniden yazmadan iyileştirilmektir.
Kodunuzu sıfırdan yeniden yazmak, yaptığınız en büyük hata olabilir, ancak aynı şekilde kodunuzu yeniden yazmamak da aynı sonuca neden olabilir.
İşte size bir tavsiye: Kodu düzenleme (refactoring) ilk seçenek olmalıdır.