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.
- 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.
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ığı.
# 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
| Tip | Belirtisi | Ne yapmalı |
|---|---|---|
| Yavaşlatan borç | O alana dokunan işler sürekli tahmini aşıyor | Faizini ölç, aynı sıraya sok. En kolay savunulan borç budur |
| Risk yaratan borç | Testi yok, geri alınamıyor, tek kişi biliyor | Gün kazandırmayabilir; bu yüzden gün değil olasılık ile savunulur |
| Sadece çirkin olan | Okurken rahatsız ediyor, başka hiçbir belirti yok | Borç 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:
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.
- Dokunduğun fonksiyondaki isimlendirme
- Eksik testi eklemek
- Ölü kodu silmek (gerçekten ölüyse)
- Yanıltıcı yorumu düzeltmek
- 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?
| Ne | Neden |
|---|---|
| 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
- 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.