Sertaç Yıldırım saha notları

Ana sayfa → Ekip Yönetimi

Teknik Borç: Ayrı Backlog Değil, Aynı Sıra

“Her sprint’in %20’sini teknik borca ayıracağız.” Kararı aldığımız toplantıdan herkes memnun çıktı. Birinci sprint %18, ikinci %12, üçüncü %5, dördüncü sıfır. Kimse kuralı iptal etmedi — her sprint sadece “bu sefer acil bir şey var” oldu.

Özet
  • Yüzde bir bütçe değil, temennidir. Ayrı kovaya konan iş önceliklendirilmez; önceliklendirilmeyen iş yapılmaz.
  • Borcu faiziyle ölç. “Kod kötü” savunulamaz; “bu modüle dokunan son 12 iş ortalama 3 gün fazla sürdü” savunulabilir.
  • Üç tip borç var, ikisi borç değil. Yavaşlatan ve risk yaratan borçtur; sadece çirkin olan estetik meseledir.
  • Ödememek de bir karardır. Altı ay sonra silinecek modülün borcu ödenmez — ama bu karar yazılır.
  • Kampçı kuralının sınırı PR boyutudur. Dokunduğun yeri temizle, ama incelemeyi öldürecek kadar değil.
  • Ayrı liste, borç mezarlığıdır. Aynı dersi postmortem aksiyonlarında da ödemiştim.

Sahadan: bir kuralın ölüm takvimi

Dördüncü sprint’in planlamasında kimse “%20 kuralını kaldıralım” demedi. Sadece masaya üç acil iş geldi ve kapasite doldu. Beşinci sprint’te de öyle oldu. Altıncıda kimse kuralı hatırlamıyordu bile.

Sonradan fark ettim: kural en baştan işlemeyecek şekilde kurulmuştu. Çünkü %20’yi korumak için her sprint yeniden savaş vermek gerekiyordu ve o savaşın hep aynı tarafı kaybediyordu. Acil işin bir sahibi ve bir tarihi vardı; teknik borcun ikisi de yoktu.

Benim hatam kuralı koymak değil, kuralı ölçüsüz koymaktı. “Kod kötü, düzeltmeliyiz” cümlesiyle masaya oturmuştum. O cümlenin karşısındaki “müşteri bu özelliği perşembe istiyor” cümlesi her zaman kazanır, çünkü birinin sayısı var diğerinin yok.

Ayrı listeye konan iş, önceliklendirilmeyen iştir. Önceliklendirilmeyen iş de yapılmaz.

Borcu faiziyle ölçmek

Teknik borcun en sinsi tarafı, bedelini tek seferde değil taksitle ödemen. Dolayısıyla ölçülecek şey kodun ne kadar kötü olduğu değil, o koda dokunmanın ne kadar yavaşlattığı.

Faizi olcmenin basit yolu
# 1) Is takip sisteminden: son 6 ayin tamamlanmis isleri
#    (tahmin edilen sure, gercek sure)
# 2) Her isin PR'larindan: hangi dizinlere dokundu
# 3) Eslestir:

modul               is sayisi   tahmin ort.   gercek ort.   fark
--------------------------------------------------------------
odeme/eski-akis         12         3 gun        6,1 gun     +3,1
katalog                 19         2 gun        2,3 gun     +0,3
bildirim                 8         2 gun        2,1 gun     +0,1

# Cikan cumle:
# "odeme/eski-akis'e dokunan her is ortalama 3 gun uzuyor.
#  Onumuzdeki ceyrekte oraya dokunan 6 is var: ~18 gun.
#  Duzeltme 5 gun surer."

Bu tablo çıktıktan sonra önceliklendirme toplantısı tamamen değişti. Artık “kaliteye zaman ayıralım” demiyordum; “5 gün harcayıp 18 gün kazanalım” diyordum. İkincisi bir mühendislik tercihi değil, bir sıralama argümanı — ve aynı dilde konuşulduğu için tartışılabiliyor.

Tablo bazen de tersini söylüyor. katalog satırı gibi: kod çirkin ama kimseyi yavaşlatmıyor. Onu düzeltmek için harcanacak gün, hiçbir gün kazandırmıyor.

Üç tip borç, ikisi gerçek

TipBelirtisiNe yapmalı
Yavaşlatan borçO alana dokunan işler sürekli tahmini aşıyorFaizini ölç, aynı sıraya sok. En kolay savunulan borç budur
Risk yaratan borçTesti yok, geri alınamıyor, tek kişi biliyorGün kazandırmayabilir; bu yüzden gün değil olasılık ile savunulur
Sadece çirkin olanOkurken rahatsız ediyor, başka hiçbir belirti yokBorç değil, tercih. Dokunduğunda temizle, iş maddesi açma

İkinci satır en çok tartışılan. Risk borcunun gün karşılığı yok; “bu servisin testi yok” demek kimsenin işini bugün yavaşlatmıyor. Onu savunmanın yolu somut bir senaryo: “Bu modülde son bir yılda iki olay yaşadık, ikisinde de kök nedeni bulmak 40 dakika sürdü çünkü testten anlayamadık.” Rakam yine olay kayıtlarından geliyor.

Üçüncü satırı borç saymamak, listeyi gerçekçi tutuyor. Her estetik rahatsızlığı iş maddesine çevirirsen liste kabarıyor ve hiçbiri yapılmıyor — sonuçta gerçek iki tip de onların arasında kayboluyor.

Aynı sıraya nasıl girer

Borç maddesi, herhangi bir iş maddesiyle aynı formda yazılıyor. Fark, gerekçe satırında:

Iyi yazilmis borc maddesi
BASLIK : odeme/eski-akis icindeki cift kod yolunu tekile indir
SURE   : 5 gun
NEDEN  : Bu module dokunan son 12 is ortalama 3,1 gun fazla surdu.
         Onumuzdeki ceyrekte 6 is daha dokunacak.
         Tahmini kazanc: ~18 gun.
RISK   : Dokunulmazsa ceyrek sonunda 2 is kaymis olur.
NASIL  : Adim adim; her adim ayri PR, davranis degismiyor,
         testler once yaziliyor.
SAHIP  : tek isim        TARIH: sprint 21

Üç şey değişiyor: sahip (ekip değil kişi), tarih, sayı. Bu üçü olduğunda madde normal backlog’ta kendini savunabiliyor. Olmadığında ayrı listeye düşüyor ve orası bir mezarlık — postmortem aksiyonlarında tam olarak aynı hatayı yapmıştım, ders aynı.

Kampçı kuralı ve sınırı

Küçük borçların büyük kısmı iş maddesi gerektirmiyor: dokunduğun yeri bir tık temiz bırak. Ama bu kuralın bir sınırı var ve sınırı koymazsan başka bir şeyi bozuyor.

Bu temizlik PR’a sığar
  • Dokunduğun fonksiyondaki isimlendirme
  • Eksik testi eklemek
  • Ölü kodu silmek (gerçekten ölüyse)
  • Yanıltıcı yorumu düzeltmek
Bu ayrı PR ister
  • Dosya taşımak, yeniden adlandırmak
  • Arayüz değiştirmek
  • Davranışı etkileyen her temizlik
  • PR’ı 400 satırın üstüne çıkaran her şey

Sebebi kod inceleme yazısında: büyüyen PR, incelemeyi susturuyor.

Karışık PR’ın asıl zararı da bu: temizlikle gerçek değişiklik aynı diff’te olduğunda incelemeci ikisini ayıramıyor ve geri alma gerektiğinde ikisi birlikte geri gidiyor.

Ödememek de bir karardır

Borcun tamamını ödemeye çalışmak, ödememeye çalışmak kadar yanlış. Bazı borçlar bilinçli olarak taşınır:

  • Ömrü kısa olan kod. Altı ay sonra silinecek modülün borcu ödenmez.
  • Nadiren dokunulan alan. Faizi yoksa anapara da önemli değildir.
  • Henüz sınırı netleşmemiş yer. Doğru soyutlamayı bilmeden yapılan temizlik, ikinci bir borç üretir.

Tek şart: karar yazılır. “Bu borcu bilerek taşıyoruz, sebebi şu, şu koşul değişirse yeniden bakarız” cümlesi bir karar kaydına geçmediğinde, altı ay sonra aynı tartışma sıfırdan başlıyor — ve bu sefer kimse neden taşındığını hatırlamıyor.

Ne izlemeli?

NeNeden
Modül başına tahmin sapmasıFaizin kendisi; borcun nerede olduğunu kod kalitesi aracından daha doğru söyler
Sıradaki çeyrekte o modüle dokunacak iş sayısıÖdemenin ne zaman yapılacağını belirler
Ayrı listede bekleyen borç maddesi sayısıSıfır olmalı; sıfır değilse liste mezarlığa dönüyor demektir
Bilerek taşınan ve yazılı olan borç sayısıArtıyorsa iyi: karar veriliyor demektir, erteleniyor değil

Bende işe yaramayanlar

  • %20 kuralı. Yukarıda anlattım: dört sprint’te öldü. Yüzde, sahibi ve tarihi olmayan bir taahhüttür.
  • “Teknik borç sprint’i”. Çeyrekte bir hafta ayırdık. O hafta herkes en sevdiği şeyi temizledi, hiçbiri en pahalı borç değildi. Ölçü olmadan ayrılan zaman, en çok rahatsız edene gidiyor — en çok yavaşlatana değil.
  • Kod kalitesi puanını hedef yapmak. Araç bir puan üretiyordu, onu yükseltmeyi hedefledik. Puan yükseldi, hiçbir iş hızlanmadı. Puan, faizin yerine geçmiyor.

Kontrol listesi

Borç maddesini masaya koymadan önce
  • Bu borç hangi tip: yavaşlatan mı, risk mi, yoksa sadece çirkin mi?
  • Faizini ölçtüm mü — bu modüle dokunan işler ne kadar uzuyor?
  • Önümüzdeki çeyrekte oraya kaç iş dokunacak?
  • Maddenin sahibi tek bir kişi mi, tarihi var mı?
  • Madde normal backlog’ta mı, ayrı listede mi?
  • Ödememe seçeneğini de değerlendirdim mi?
  • Ödememe kararı verdiysem, yazılı mı?
  • Temizlik PR’ı gerçek değişiklikle karışıyor mu?

Sonuç

%20 kuralı öldükten sonra yerine bir kural koymadık. Onun yerine tek bir tablo yaptık: hangi modüle dokunan işler ne kadar uzuyor. Sonraki çeyrekte teknik borç maddelerinin toplam payı kabaca yine beşte bir civarındaydı — ama bu sefer kimse yüzde konuşmuyordu, çünkü her madde kendi gerekçesiyle sıraya girmişti.

Teknik borcu koruma altına almaya çalışmak, onun savunulamaz olduğunu kabul etmek demek. Savunulabilir hâle getirirsen korumaya ihtiyacı kalmıyor.

Test şu: en büyük teknik borcunu, ürün tarafındaki birine gün cinsinden anlatabiliyor musun? Anlatamıyorsan sorun ürün tarafının anlamaması değil; senin henüz ölçmemiş olman.