Teknik borç (Technical Debt), geliştirmedeki tavizlerin bedelini tanımlayan bir metafordur: optimal olmayan kararlar ne kadar hızlı alınırsa, o kadar fazla faiz birikir. Terim, 1992 yılında Ward Cunningham tarafından, düşük kaliteli kodu finansal borca benzeterek ortaya atılmıştır. Martin Fowler'a göre teknik borç kaçınılmazdır, ancak onun bilinçli yönetimi profesyonel bir ekibi kaotik olandan ayırır.
Önemli Noktalar
Teknik borç, ilk olarak 1992'de OOPSLA'da Ward Cunningham tarafından önerilen bir metafordur. Programlamayı yatırıma benzetti: dikkatsiz kod, kredi çekmek gibidir. Faizi, bakım, hata düzeltme ve yeni gereksinimlere uyum sağlama için harcanan ek süre şeklinde ödenir. Borcun her zaman kötü olmadığını anlamak önemlidir; stratejik borç haklı görülebilir.
Finansal benzetme neredeyse kelimesi kelimesine çalışır. Bir ekip borç alırsa (bir son teslim tarihine yetişmek için ideal olmayan kodu yayınlarsa), faiz ödemek zorundadır. Faiz, geliştirmenin yavaşlaması, kod değiştirirken hatalar ve yeni geliştiricileri işe almanın karmaşıklığıdır. Faiz, yeniden düzenleme maliyetinden daha yüksek olduğunda, borcu ödeme zamanı gelmiştir. Ana sorun: banka kredisinin aksine, geliştiriciler her zaman borç aldıklarının farkında olmazlar.
Önemli bir açıklama: teknik borç ≠ kötü kod. Kötü kod, yetersizliğin sonucudur. Teknik borç bilinçli bir tavizdir. Ekip, kusurlu bir şey yaptığını anlar, bunu teknik dokümantasyona kaydeder ve iyileştirmek için geri dönmeyi planlar. Borç ve kötü kod arasındaki fark, kararın bilincinde yatar. Bu nedenle borç yönetiminin ilk adımı, varlığını kabul etmektir.
Teknik borcu sınıflandırmak, doğasını anlamaya ve doğru geri ödeme stratejisini seçmeye yardımcı olur. Martin Fowler, iki eksenli bir çeyrek modeli önerdi: kasıtlı/kasıtsız ve pervasız/ihtiyatlı. Her kombinasyon farklı bir yaklaşım gerektirir. Bir mobil geliştirme ekibinin karşılaştığı ana borç türlerine bakalım.
Kasıtlı Borç — ekip, bir son teslim tarihine yetişmek için bilinçli olarak optimal olmayan kodu yayınlamaya karar verir. Örnek: hipotez doğrulamasından sonra ViewModel'in alana göre birkaç parçaya bölüneceğini bilerek tek bir monolitik ViewModel ile MVP başlatmak. Bu borç backlog'a kaydedilir ve planlı bir geri ödeme tarihi vardır. Plan olmadan, kasıtlı borç kronik hale gelir.
Kasıtsız Borç — bilgi eksikliği, kod inceleme eksikliği veya kötü süreçler nedeniyle kalitesi beklenenden düşük olan kod. Örnek: bir geliştirici Room DB ile çalışmanın en iyi uygulamalarını bilmiyordu ve UI iş parçacığında sorgular yazarak ANR'ye neden oldu. Bu borç türü en sinsi olanıdır — ekip, kritik performans sorunlarıyla karşılaşana kadar bunun farkına varmaz.
Mimari Borç — kalıpların veya proje yapısının yanlış seçimi. Örnek: ağ üzerinde soyutlama katmanı olmayan ve Retrofit'in doğrudan ViewModel'den kullanıldığı bir uygulama. Retrofit'i Ktor ile değiştirmek, tüm ViewModel'lerin değiştirilmesini gerektirir. Mimari borcu düzeltmek en maliyetlisidir, bu nedenle mimari düzeydeki kararlar azami dikkatle alınır.
Kod Borcu — tek bir sınıf veya yöntem içindeki yerel optimallik eksiklikleri. Örnek: UI, iş mantığı ve veri işlemenin karıştığı 200 satırlık uzun bir yöntem. Extract Method ile 15 dakikada düzeltilir. Kod borcu daha az kritiktir, ancak proje ölçeğinde birikmesi geliştirmeyi mimari borçtan daha az yavaşlatmaz.
Test Borcu — Birim testleri, UI testleri veya entegrasyon testlerinin eksikliği. Her manuel regresyon çalıştırması bu borcun faizidir. Bir projede otomatik test yoksa, herhangi bir değişiklik saatlerce manuel test gerektirir. Google Testing Blog'a göre, test kapsamı >%70 olan projeler, üretime 2 kat daha az hata gönderir.
Dokümantasyon Borcu — mimari dokümantasyonun, karmaşık kod alanlarındaki yorumların, işe alım readme'sinin eksikliği veya güncelliğini yitirmesi. Dokümantasyon olmadan yeni bir geliştirici alışmak için haftalar harcar. Çözüm: Mimari Karar Kayıtları'nı (ADR) tutmak ve dokümantasyonu her görev için Tamamlanma Tanımı'nın (Definition of Done) bir parçası haline getirmek.
| Borç Türü | Örnek | Düzeltme Zorluğu |
|---|---|---|
| Mimari | Yanlış kalıp seçimi | Yüksek (haftalar) |
| Kod | Uzun yöntem, tekrar | Düşük (saatler) |
| Test | Birim test eksikliği | Orta (günler) |
| Dokümantasyon | Güncel olmayan ADR | Düşük (saatler) |
Bileşik faiz etkisi teknik borcun ana tehlikesidir. Optimal olmayan kodun her yeni katmanı, sistem karmaşıklığını doğrusal olarak değil, üstel olarak artırır. Basit bir örnek: A modülü B modülüne bağlıysa ve her ikisi de borç içeriyorsa, A'yı değiştirmek B'deki borcu anlamayı gerektirir. 10 yinelemeden sonra, bir geliştirici zamanının %80'ini bağımlılıkları çözmeye ve sadece %20'sini yeni işlevselliğe harcar.
Pazara çıkış süresinin yavaşlaması borcun doğrudan bir sonucudur. Ekip, bakıma giderek daha fazla zaman ve yeni özelliklere daha az zaman harcar. Stripe (2023) araştırması, geliştiricilerin iş değeri yaratmak yerine teknik borçla uğraşarak haftada ortalama 17 saat harcadığını gösterdi. Mobil geliştirmede bu, her biri kendi platform güncellemelerine sahip iki platformu destekleme ihtiyacı nedeniyle daha da kötüleşir.
Ekip tükenmişliği belirgin olmayan ancak yıkıcı bir sonuçtur. Her değişikliğin diğer üç şeyi bozduğu bir kodda çalışmak kronik strese neden olur. Geliştiriciler ürünle gurur duymayı bırakır, motivasyon düşer ve personel devir hızı artar. Stack Overflow Survey 2024'e göre, eski kodla çalışmak, düşük maaştan sonra iş memnuniyetsizliğinin en yaygın ikinci nedenidir.
Fowler'ın Çeyreği borcu önceliklendirmek için pratik bir araçtır. İki eksen: kasıtlı/kasıtsız ve pervasız/ihtiyatlı. Pervasız kasıtlı borç: “testler için zamanımız yok, testsiz yayınlayın.” İhtiyatlı kasıtlı: “testlerin gerekli olduğunu biliyoruz, ancak şimdi özelliği yayınlamak daha önemli — bir sonraki sprintte testler için bir görev oluşturacağız.” Birincisi acil müdahale gerektirir, ikincisi izleme gerektirir.
İzci Kuralı stratejisi — “kamp alanını bulduğundan daha temiz bırak.” Basit bir kural: bir yöntemi değiştirirken, onu biraz daha iyi hale getirmek için %10 daha fazla zaman harca — bir değişkeni yeniden adlandır, 50 satırlık bir bloğu ikiye böl. Ekip ölçeğinde bu yaklaşım, yeniden düzenleme için ayrı sprint'ler ayırmadan borçta kademeli bir azalma sağlar. İyileştirme mikroskobik ancak düzenli olmalıdır.
Zaman ayırmak borç yönetimi, ekip olgunluğunun bir işaretidir. Sprint'in %15-20'sinin teknik iyileştirmelere ayrılması önerilir. Bu, ekibin haftada bir gün yeniden düzenleme dışında hiçbir şey yapmadığı anlamına gelmez. Teknik görevler eşit olarak dağıtılır: metrikleri iyileştirme, sıcak noktaları yeniden düzenleme, bağımlılıkları güncelleme. Ayrılmış zaman olmadan borç sürekli büyür.
// İzci Kuralı stratejisi eylemde
// Önce: sihirli sayılarla okunamaz yöntem
fun calc(a: Int): Int = a * 60 * 1000
// Sonra: sabitlerle okunabilir yöntem
private const val SECONDS_IN_MINUTE = 60
private const val MILLIS_IN_SECOND = 1000
fun minutesToMillis(minutes: Int): Int =
minutes * SECONDS_IN_MINUTE * MILLIS_IN_SECOND
Otomasyon borç tespiti, yönetimin üçüncü ayağıdır. Uzun yöntemleri (>30 satır), sınıfları (>500 satır), aşırı iç içe geçmeyi (>5 seviye) tespit etmek için uyarılar ayarlayın. Pull request'lerde otomatik yorumlar için Danger veya benzer araçları kullanın: bir yöntem karmaşıklık eşiğini aşarsa, bot “Bu yöntemin döngüsel karmaşıklığı 12'dir — lütfen bölmeyi düşünün.” yazar. Otomasyon, kod inceleme yükünü azaltır.
SonarQube teknik borç analizi için en popüler platformdur. “Düzeltme günü” hesaplar — yöneticiler için anlaşılabilir bir metrik. SonarQube, Kotlin, Swift, Java, Python ve diğer dilleri destekler. CI/CD pipeline'ına entegre olur ve borç eşiği aşarsa pull request'leri reddeder. Mobil ekipler için bu fiili standarttır.
Android ekipleri için Detekt (Kotlin statik analizi) ve Android Lint de kullanılır. Detekt, kod metriklerini hesaplar ve Code Smell kalıplarını bulur. SonarQube Android Gradle eklentisi, sonuçları tek bir raporda birleştirir. iOS ekipleri için — statik analiz için SwiftLint ve kullanılmayan kodu bulmak için Periphery. Xcode Organizer, genellikle mimari borçla ilişkili performans metriklerini gösterir.
CodeClimate ve CodeFactor, GitHub/GitLab depolarını analiz eden ve borç dinamiklerini gösteren bulut çözümleridir. Her commit'i değerlendirerek borcun ne zaman büyümeye başladığını izlemeyi sağlarlar. Sürdürülebilirlik grafiği, yönetimle iletişim kurmak için anlaşılabilir bir araçtır: “Mart ayındaki zirveyi görüyor musunuz? Bir sürümü hızlandırdığımızda ve 3 günlük düzeltme borcu biriktirdiğimiz zamandı.”
Sıkça Sorulan Sorular
Kredi metaforunu kullanın: “Özelliği şimdi 2 haftada yayınlayabiliriz, ancak sonraki her sprint'te bakıma %20 daha fazla zaman harcayacağız. Borcu ödemezsek, 6 ay içinde bir sprint 2 hafta yerine 3 hafta sürecek.” Yöneticiler finansal benzetmeyi sezgisel olarak anlarlar.
MVP ve deneyler için — evet, bir geri ödeme planı belgelenmişse. Yarına yatırımcıya prototip göstermesi gereken bir startup için — evet. Bir milyon kullanıcılı bir ürün için — hayır, hatanın bedeli çok yüksek. Ana koşul: planlı bir düzeltme tarihi ile bilinçli bir karar.
SonarQube “Debt Ratio” gösterir — düzeltme süresinin geliştirme süresine oranı. Debt Ratio < %5 normal kabul edilir. Kod için: Yöntem Başına Kod Satırı, Döngüsel Karmaşıklık, Tekrar Oranı. Süreçler için: hata süresinin özellik süresine oranı.
Hayır — bu son çaredir. Uygulama, her sprint'in %15-20'sini teknik iyileştirmelere ayırmanın bir “yeniden düzenleme sprint'i” nden daha etkili olduğunu göstermektedir. İş değeri olmayan yeniden düzenleme, zaman kaybı olarak algılanır. İyileştirmeleri her ürün görevine dahil etmek daha iyidir.
Hayır — stratejik borç bir araç olabilir. Bir ekip, gelir getirecek bir özelliği yayınlamak için bilinçli olarak borç alır ve sonra öderse — bu etkili yönetimdir. Sorun, borç kontrolsüz bir şekilde biriktiğinde ve kimsenin ne kadar “faiz” biriktiğini bilmediğinde başlar.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun