Fazlamesai'ye soralım: Yeniden yazmak ya da yazmamak

3
tongucyumruk

Geçtiğimiz günlerde Joel Spolsky'nin Asla Yapmamanız Gereken Şeyler, Bölüm 1 başlıklı yazısına denk geldim. Oldukça eski tarihli bu yazı, Netscape 6 örneğinden başlayarak halihazırda varolan bir yazılımı sıfırdan yeniden yazmanın ne kadar yanlış bir hareket olduğundan bahsediyordu.

Profesyonel yazılım geliştirme ortamlarında her daim bir tartışma konusu olan bu soruyu, herkesin "abi bunu xyz ile sıfırdan yazarım ben x günde" dediği bir dünyada, bir de Fazlamesai'ye soralım dedim: Eğer elinizde bir şekilde çalışan, gereksinimleri karşılayan bir ürün varsa, bunu yeniden yazmak ne kadar doğru bir harekettir? Ne koşullar altında kabul edilebilir bir eylem sayılır? Hangi koşullar altında şirketinizin sonunu getirecek bir hamle olur?

Buyurun bakalım tartışmaya.

Görüşler

0
tongucyumruk

Kendimce bu soruyu yanıtlamaya çalışayım: Yazmamak! (uygun koşullarda)

Daha çok web geliştirme ile uğraşan bir insan olarak o bağlamda cevaplamak istiyorum. Web uygulamalarının en güzel yönü tamamen sunucu tarafından idare ediliyor olmaları. Bu sayede yazılımın bir veya birden fazla kısmını dilediğiniz zaman dilediğiniz şekilde değiştirme imkanınız oluyor. Bu nedenle herhangi bir yazılımı güncel tutmak için sıfırdan yeniden yazmak gerektiğine inanmıyorum.

Kişisel tecrübemden yola çıkarak söyleyebilirim ki, bu konuda en sıkıntılı konulardan biri üzerinde çalıştığınız sistemin düzgün bir şekilde katman izolasyonuna sahip olmamasıdır. Bu nedenle herhangi bir sistemi güncel hale getirmek gerektiği zaman genelde izlenebileceğine inandığım bir çizelge var:

  1. Yeni özellik geliştirmeyi yavaşlatın. Eğer siz tek başınıza sistemi güncellemeye çalışırken 10 kişilik bir ekip eski yapının üzerine daha da çirkin katmanlar inşa ediyorsa başarı ihtimaliniz ciddi biçimde azalır. Bu yeni özellik geliştirmeyi tamamen durdurun demek değil tabi ki, lakin yeni özellik geliştirme sürecinin altyapı güncellemeleri ile senkron içinde hareket etmesi kritik öneme sahip.
  2. Sisteminizin önyüzü ile arkaplandaki sistemini birbirinden ayırmaya başlayın. Eğer önyüz'de çalışan bir iş mantığı var ise onu arkaplana aktarın.
  3. Önyüz ile arkaplandaki servisler arasındaki etkileşimi düzgün bir biçimde tanımlayan bir arayüz üretin.
  4. Bu arayüz için testler yazın. Özellikle ilk testlerinizi yazmak hiç kolay olmayacaktır ama test yazmak böyle birşey, yazdıkça hzlanıyorsunuz.
  5. Arkaplandaki servislerinizi parça parça güncellemeye başlayın. Her değişiklikten sonra testleri çalıştırarak önyüzün herhangi bir beklentisini kırmadığınızdan emin olun.
  6. Bu noktada önyüzünüz tek hamlede güncellenebilecek kadar basite indirgenmişse önyüzünüzü güncelleyin, eğer önyüzünüz bunun için fazla karmaşıksa önyüzünüzü modüllere bölerek parça parça güncelleyin.
  7. Geçmiş olsun.

Bu konuyla daha çok ilgilenen arkadaşlara Bob Amca'nin efsanvi kitabı Clean Code ve Michael Feathers'ın Working Effectively With Legacy Code kitaplarını tavsiye ederim. İyi okumalar.

1
yuxel

Spolsky'nin yazısını çok önceleri okumuştum. 4 sene kadar önce de acizane şöyle bir şeyler karalamıştım. http://yuxel.net/?module=news&action=show_id&id=501

Son 8 aydır, Dubai'de bir şirkette çalışıyorum. Bundan 6 ay kadar önce bir proje geliştirmeye başladık. Biz ilk versiyonu 2 kişi ile, 2 ayda tamamladık ve 2 ayda site yayına çıktı. Bunu geliştirirken 2 kişiydik. Bazı yerleri hız baskısı yüzünden "pataküte" yazdığımız oldu. Ancak bunların hepsi kodda TODO veya Jira'da "technical debt" olarak açıldı. Velhasıl, planda ekibe yeni katılanlar olunca bu "boktan" yerleri periodik olarak düzenleyeceğimiz refactoring hackathon'ları ile düzenleyecektik.

Projeyi 2 ay içinde çıktık, 1 ay kadar da yavaş yavaş geliştirmesine devam ettik. Satışlar falan gayet iyiydi, site ufak tefek sorunlar haricinde "yağ gibi akıyordu". Marketing ekibi ve "üsttekiler" bize "magician" flan diyordu.

Bu 1 aylık süreçte ekibe 5 yeni developer katıldı. Neredeyse hepsinin iş görüşmesini ben yaptım. Aralarından bir tanesi "zehir" gibi bir çocuktu. Ancak yetkiliye "bu çocuk zehir gibi, ama burada sıkılır, oturur kodu baştan yazmaya kalkar" diye de ilettim. Yönetici "bırakalım yazsın o zaman :)" diye gülümsedi.

Çocuklar ekibe katıldı, ilk iki haftalık süreçte oryante oldular. Ve 2 hafta sonra içerden "bu kod çok kötü, neden burada şu şu işleri yaptık, burada daha 'hipster' teknolojiler kullanabilirdik" gibi yakarışlar doğmaya başladı. Bir oturum yaptık, yönetici, ben ve yeni gelen 5 arkadaş arasında bir oylama ile kodun yeniden yazılmasına karar verildi.

Kodun yeniden yazılmasına gerek olmadığını, o hata diye belirtilen yerlerin hepsinin zaten todo listemizde olduğunu ve bunların hepsini benim tek başıma iki haftada düzeltebileceğimi söylemiştim.

Ancak içerdeki ben hariç herkes "biz zaten hep beraber girersek kodu 2 haftada cillop gibi yaparız" demişlerdi. Demokrasi hakim geldi kodun yeniden yazılımı başladı. Ben ise bu fail içinde yer almak istemiyorum diye rewrite projesinde yer almadım.

Rewrite'dan önce, kodun testleri, code style guide'ları, continous delivery'si ve continous integration'ları her şeyi hazırdı. Ve bunu 2 ayda, hiçbir bussiness gereksinimi netleşmemiş koşullarda yapmıştık. Şu anda, kodda tüm business logic, uygulanan tüm teknolojiler vs vardı. Ve site, üzerinden çok sayıda siparişin geçtiği bir yapıyla, 20ms gibi bir sürede performans verecek şekilde çalışıyordu. Bölgedeki en hızlı site idi.

Rewrite'a başladılar. Vaadettikleri "2 haftada cillop gibi yazarız"ın 9. haftasında kodu yayına alabildiler. Tahmin edebileceğiniz gibi her yeri patlayan bir ürün ortaya çıktı. Gelirler marketing ekibinin dediğine göre %80 azaldı.

Şu anda "rewite"ın 12. haftasındayız; hala continous delivery'miz yok. Kodu elle deploy ediyorlar. Hala bir sürü bug'ımız var. Ve sitemiz 600ms'de render oluyor.

Şu anda, içerdeki ekip, deadline'ı 2 hafta sonra olan, aslında 1.5 ay önce testlerine başlanması gereken bir sistemi yetiştirmeye çalışıyor. Sistemin yayına girmediği her hafta şirketin kaybedeceği para milyon dolar civarında.

Günün sonunda; 3-5 developer'ın egosunu okşaması için heba olan milyon dolar; ve bu stres altında çalışmaya mahkum kalan (ben hariç) 6 developer, "gelirler %80 düştü, naptınız siteye" diyen bir marketing ekibi var.

"İyi kod" diye bir şey her zaman geçerli bir sebep değil. Çünkü o "iyi" dediğiniz kodlama şekli, o "iyi" dediğiniz "hipster teknolojiler" 6 ay sonra değişecek. Önemli olan, kodu temel yazılım prensiplerine uygun şekilde, bakımı kolay, katmanlı mimari ile vs yazmak.

Yazılımcıda aranan en büyük kriterlerden birisinin ise "iyi kod yazmak"tan ziyade "kötü kodu refactor edebilme" olması gerektiğini düşündüğümü belirtir, bu yorumuma burada son veririm.

0
FZ

"biz zaten hep beraber girersek kodu 2 haftada cillop gibi yaparız"

Meshur son sözlerden.

0
kulker

"Bu anlatılan bizim hikayemizdir"

0
irfaN

Yeniden yazmamak tarafında oyumu kullanıyorum.

"refactoring'in başarı hikayesi" bizimkisi..

Şu anda çalıştığım proje, flex ile yazılmış bir marketing uygulaması. JavaScript ile baştan yazılması için ~2 yıl kadar önce başlanmış, fakat o kadar karmaşık ve dağınık bir yapı var ki, backend toparlanmadan frontend'in adam olması mümkün değil, her bir request için data mapper yazmanız gerekiyor, gelen response'u browser'da kullanabilmek için 4 defa çeviriyorsunuz. "3 ay'da çıkartırız abi" diyen arkadaşlar öleli çok oldu, gömdük onları kodun derinliklerine.

Şef Mimar olarak 10 ay önce başladım projeye, 3 ayrı yönetici değiştirdim. Her bir yöneticinin bana "Çok kötüyse baştan yazabilirsiniz" tekliflerini her geri çevirdiğimde tırsmadım da değil, "ya toparlayamazsak?" sorusu hep korkuttu beni.

Browser'a 12MB javascript yüklenen bir uygulamadan bahsediyoruz, scale'i belirtelim de, "nasıl ~2 yıl ya!??" sorularına cevap olsun.

10 ay önce, Şubat ayında, çalışan bir uygulama yoktu ortada. Her bir "tık" konsola bi hata atıyor, hiç bir şey çalışmıyor. "pata küte" çalışır hale gelmesi yaklaşık 3 ay sürdü. Fakat performans çok kötü, bir tık 10.000ms'e mal oluyordu.

10 ay sonunda, 2500 mili saniyede render olan, bır tık'ın maaliyeti 300 milisaniye olan bir ürün elde ettik. Sabırla, parça parça unit test yazılmasına ve refactor'e başladık, şu anda 700+ unit test yazılmış, (testlerin büyük bir kısmı black box yapıda, derine girmemek için) çatır çatır çalışan, eski yapı üzerine yeni spagettiler eklemeden yeni feature'lar geliştiriyoruz.

Şu an da geriye dönüp bakıyorum da, 10 ay gibi bir sürede bırakın "ürün" elde etmeyi, business gereksinimlerini anca kavrardık.

0
fmatak

hem yeniden yazma, hem de refactoring projelerinde yer aldım. ikisinin de fail ettiğine yada başarıya ulaştığına şahit olduğum durumlar oldu. ama büyük oranda sonuç istenenin altında vasat bir görüntü oluyor. bunun çeşitli sebeplerini kendimce şöyle sıralamak istiyorum: 1) var olan projenin küçümsenmesi (under-estimate) (bkz: 2 haftada cillop) 2) yeni yazılacak projenin küçümsenmesi (bkz: 2 haftada cillop) 3) kodlama dışı kısmın küçümsenmesi: 3rd parti entegrasyonları, business tarafının isteyeceği değişiklikler, bunlarla ilgili son kararların verilmesi, hazır yeniden yazılıyorken şu iş akışlarını da değiştirelim vs gibi değişiklik istekleri 4) ekibin gücünün büyütülmesi: (over-estimate) tek başıma 50bin satırlık projeyi 3 ayda bitirdim, 10 kişi bir milyon satırlık işi şu kadar sürede çok rahat yaparız kafası. Ekip büyüdükçe verimlilik liner olarak artmamakta, aksine düşmekte. iletişim için 2^n adet olası küme oluşabiliyor. bunların her birinin aldığı kararlar diğerlerini etkileyebiliyor. sadece ekibin büyümesi bile işleri yavaşlatabiliyor. 5) projeye eklenen 3üncü modül ile 20inci modülün aynı zorlukta olduğunu düşünmek: 3üncü modülü eklediğinizde, elinizdeki diğer 2 modülle uyumlu çalıştığını garanti etmeniz yeterli olacakken, 20inci modülün ayağına basmadan çalışması gereken modül sayısı 19. bunun kontrolü, garanti edilmesi vs. i ilkine göre kat kat uzun sürer ve zor olur. zaman planlamasında ikincisine bekli 5 kat daha uzun süre ayırmak gerekebilir duruma göre. 6) var olan proje ile hayal edilen proje arasındaki uzaklığın dikkate alınmaması: bu uzaklık, aslında refactor mü yapılsın yoksa yeniden mi yazılsın bunun kararını vermek için kullanılması gereken birkaç kritik metrikten biri. (bir diğeri için development vs. maintenance cost) Sizin elinizde bir e-ticaret sistemi altyapısı varsa, ama gitmek istediğiniz yer bir haber sitesi ise, "zaten kullanıcı login vs kısımları hazır. bunu refactor edelim" yaklaşımı doğru olmayabilir. diğer yandan, amacınız var olan siteninizin ön yüzünü değiştirmekse, tekrar yazmak mantıksız olabilir. 7) küçük ama emin adımlar atmak yerine devasa adımlar atmaya çalışmak. devasa adımlar daha dikkat çekici olabilir. üst yönetimden daha çok takdir alabilir. ama devasa bir adım atabilmek için uzun süreye ihtiyaç vardır. ve bu uzun sürenin, özellikle büyük ekiplerde, ekip değişimlerine denk gelmesi kaçınılmazdır. bu durumda ekibe yeni gelen - ekipten ayrılan kişilerin işlerinin devredilmesi, yeni iş bölümlerine gidilmesi ve yeni uyum süreci zaten uzun sürecek olan dev adımın daha da uzun sürmesine sebep olacaktır. ayrıca birisi tarafından başlanıp, tamamlanmadan başkası tarafından devranılan işlerin başarılı olma oranı daha düşük olmaktadır. sadece yarım bırakan kişinin kafasında kalmış olan çeşitli kısımlar, ileride eklemeyi planladığı kontroller vs. yüzünden işler karışmaktadır. 8) sadece refactoringe özel olmayan, genel yazılım proje sıkıntıları. ör: yönetimin teknik konulara müdahale etmekten kaçınmaması, ekibe güvenmemesi, ekibin yönetime güvenmemesi, bu yüzden iki tarafında bir birinden gizli işler çevirmeleri, tutamayacakları sözler vermeleri vs. gibi.

daha çok şey yazılabilir aslında. ama genel olarak 10 durumun en az 8inde refactoring'in daha iyi bir seçenek olarak karşımıza çıktığınız düşünüyorum.

0
ybp

Bu çok değişkenli bir denklem. Gereksinimler, kimin yazacağı, projenin sahibinin yazılım ekibinin bir parçası olup olmadığı, yeniden yazmak ya da refactor etmenin ekibinize katacağı tecrübe, zaman, para ...

Ben "yeniden yazalım" tarafındayım. Yukarıdaki etkenler ve daha fazlası bağlamında benim için oklar yeniden yazmayı gösterdi çoğunlukla.

Refactor ederken saçlarını döküp, coğrafya ya da telefon numarasını değiştiren çok insan tanıyorum...

0
feldrim

3 yıl önce tamamlanan bir yeniden yazma süreci sonrasında, geliştiricilerin ve bu süreci yönetenlerin değişmesi, eski ve kötü tasarlanmış veritabanının aynen kullanılması, iş süreçlerinin iyileştirilmesine gidilmemesi, eski modüllerin zamanla yeni framework'e aktarılması sırasında kolaycı yaklaşımlar, dokümantasyon diye bir şeyin hiç var olmaması gibi etkenler sayesinde refactoring ve yeniden yazmanın başa baş mücadele ettiği bir legacy sistemle karşılaşınca insan bu ikilemin ağırlığını anlıyor.

Görüş belirtmek için giriş yapın...

İlgili Yazılar

Google Görüşme Üniversitesi: Web Geliştiricisinin Yazılım Mühendisliğine Yolculuğu

butch

John Washam, eğitimini ekonomi alanında tamamlamış ama kariyerini web programcısı olarak yapmış biri. Başarılı olan bir kaç iş de kurmuş. Hayatını bu alandan kazanıyor. Kariyerini, çocukluğunda hayal ettiği yazılım geliştiricilik üzerine kurduğunu, iyi bir yazılımcı olduğunu düşünürken bunun doğru olmadığı gerçeğiyle yüzleşmiş. Bundan birkaç yıl önce iş aramaya karar verdiğinde, aslında...

Fazlamesai'ye soralım: Türkçe Soru/Cevap sitesi bir ihtiyaç mı?

butch

Stack Overflow'un, soru / cevap konusunda dünyayı ele geçirme macerası, çokça itiraz eşliğinde devam ediyor. Hemen her teknik sorumuza karşılık bir tartışma ve olası cevaplar bulmak mümkün. Ama soruyu doğru biçimde ve tercihen İngilizce olarak sormanız gerekiyor. Bu da probleminizi Ingilizce ifade edecek derecede dile hakim olmanızı gerektiriyor. Ülkemiz yabancı dil anlamında ciddi bir...

Fazlamesai'ye soralım: 2017'de ne öğrenmeli?

butch

2017 kapıya dayandı. Türkiye için ekonomik açıdan sarsıntılı bir yılı geride bırakmak üzereyiz. Kafalar çok karışık, çoğumuz nasıl hareket etmemiz gerektiğini sorguluyoruz. Kimimiz var olan düzenini korumaya çalışıyor, kimimiz girişim yapmak için en uygun zamanda olduğunu düşünüyor.

Bugün Hacker News'de gördüğüm "2017'de ne öğrenmeyi düşünüyorsunuz?" başlığının burada da yer...

Fazlamesai'ye Soralım: Ağ üzerinden dosya paylaşımı için hangi dosya sistemi?

tongucyumruk

Zakkum'un gönderdiği UDOO X86: Raspberry Pi tarzı (daha güçlü) bilgisayar! linkindeki "küçücük fıçıcık içi dolu bilgisayarcık" cihazını görünce ister istemez bir kere daha evimde kullanmak üzere bir NAS cihazı kurma iştahım kabardı. Vaktiyle bir Raspberry Pi ile kurduğum dosya sunucusu ihtiyacımı görse de ne yazık ki "fazlamesaici" isteklerimi karşılamakta yetersiz...

Fazlamesai'ye soralım: 2018'de ne öğrenmeli?

murat

2018 de geldi, geçiyor. @butch'un "Fazlamesai'ye soralım: 2017'de ne öğrenmeli?" yazısını görünce bu konuyu 2018 için de hortlatmak gerektiğini düşündüm.

Ben öğrenecek yeni bir programlama dili arayışındayım. Şuan için seçeneklerim şu şekilde: python, go, elixir ve clojure.

Sizce 2018'de ne öğrenmeli?