Mert Özen Her Satırda Daha İleri
Proje Yönetimi Agile Mindset — #03

Extreme Programming (XP): Agile'ın Mühendislik Tarafı

Mert Özen 8 Kas 2026 8 dk 2 görüntülenme
Extreme Programming (XP): Agile'ın Mühendislik Tarafı

Extreme Programming (XP), Agile'ın kodun içinde yaşayan tarafıdır: test-first, pair programming, continuous integration, küçük release'ler, refactoring ve collective code ownership birbirini destekleyen bir sistem oluşturur. Scrum bu pratikleri tanımlamaz ve Fowler'ın Flaccid Scrum uyarısı tam bu boşluğu anlatır; Bookstore'un ücretsiz kargo kuralını bir pair'in test-first yazıp dakikalar içinde trunk'a küçük commit'lerle taşımasını gerçek çıktılarla gösteriyoruz.

Sürüm notu: Bu yazıdaki kodlar .NET 10 ve xUnit v3 4.0.2 ile derlenip denenmiştir; XP (Extreme Programming) tarafında Kent Beck'in "Extreme Programming Explained" kitabının iki baskısını (1999 ve Cynthia Andres ile 2004) ve Martin Fowler'ın 2009 tarihli "Flaccid Scrum" yazısını esas alır.

Önce Tahmin Et

Bookstore ekibi bir yıl önce Scrum'a geçti. İlk altı ay her şey iyi gitti: sprint'ler düzenli, review'lar keyifli, Product Owner memnun. Sonraki altı ayda velocity yavaş yavaş düştü. Her yeni feature beklenenden uzun sürüyor, her release'ten sonra iki üç hata çıkıyor, ekip "bu modüle dokunmayalım" demeye başladı. Sprint Planning, Daily Scrum, Review ve Retrospective eksiksiz yapılıyor.

Tahmin et: Scrum'ın hangi event'i ya da artifact'i eksik? Yoksa sorun Scrum'ın hiç tanımlamadığı bir yerde mi?

XP Nereden Geldi?

Extreme Programming, Kent Beck'in 1996'da Chrysler'ın C3 (Chrysler Comprehensive Compensation) adlı bordro projesinde ekibe uyguladığı pratiklerden doğdu. Beck bu deneyimi 1999'da "Extreme Programming Explained" kitabında topladı; 2004'te Cynthia Andres ile birlikte yazdığı ikinci baskıda yaklaşımı genişletti ve pratikleri yeniden düzenledi. Ward Cunningham ve Ron Jeffries de XP'nin ilk dönemindeki önemli isimler; ikisi de 2001'de Snowbird'deki 17 kişi arasındaydı.

"Extreme" kelimesi pratiklerin kendisini değil, dozunu anlatır. Beck'in fikri basit: code review iyiyse, kodu sürekli review et, yani pair programming yap. Test iyiyse, testi kod yazmadan önce yaz. Entegrasyon iyiyse, günde birçok kez entegre et. Kısa döngü iyiyse, release'leri olabildiğince küçült. İyi bilinen pratikleri alıp düğmeyi sonuna kadar çevirmek.

Değerler: Communication'dan Respect'e

XP'nin beş değeri var. İlk baskıda dört değer vardı: communication, simplicity, feedback ve courage. İkinci baskıda beşincisi, respect eklendi.

Communication, ekipteki bilginin tek bir kişide kalmamasını ister. Simplicity, bugün gereken en basit şeyi yapmayı, yani manifestonun onuncu prensibini ve YAGNI'yi (You Aren't Gonna Need It) anlatır. Feedback, her ölçekte hızlı geri bildirim ister: saniyeler içinde test sonucu, dakikalar içinde CI (Continuous Integration) sonucu, günler içinde kullanıcı tepkisi. Courage, gerektiğinde kodu atmayı, büyük bir refactoring'e girişmeyi ve "bu tahmin gerçekçi değil" demeyi kapsar. Respect ise diğer dört değerin zemini: ekip üyeleri birbirinin işine ve katkısına saygı duymadan iletişim de cesaret de çalışmaz.

Pratikler: Kodun Etrafındaki Disiplin

XP'yi diğer Agile yöntemlerden ayıran şey, pratiklerinin büyük kısmının doğrudan koda ilişkin olması. Bu seri açısından en önemlileri şunlar:

  • Test-first ve TDD (Test-Driven Development): önce başarısız olan bir test, sonra onu geçiren en basit kod, sonra refactoring.
  • Pair programming: iki geliştirici, tek bir iş üzerinde aynı anda çalışır; biri yazar, diğeri yönü ve tasarımı düşünür, roller sık değişir. Sonradan yaygınlaşan mob programming aynı fikri bütün ekibe genişletir.
  • Continuous integration: herkes değişikliğini günde en az bir kez ana hatta entegre eder ve otomatik build ile testler her entegrasyonda çalışır.
  • Small releases: sistemi gerçek kullanıcıya küçük ve sık parçalar hâlinde çıkarmak.
  • Refactoring ve simple design: davranışı değiştirmeden tasarımı sürekli iyileştirmek ve bugünkü ihtiyacı karşılayan en basit tasarımda kalmak.
  • Collective code ownership: kodun herhangi bir parçasını ekipteki herkes değiştirebilir; "bu modül Ali'nin" diye bir şey yoktur.
  • Sustainable pace: ilk baskıda "40 saatlik hafta" adıyla, ikinci baskıda "energized work" adıyla geçen pratik; yorgun bir ekip kalitesiz kod yazar.

Bu pratiklerin hiçbiri tek başına yeni değildi. XP'nin katkısı, onları birbirini destekleyen bir sistem olarak sunmasıydı: refactoring testler olmadan tehlikelidir, collective ownership testler ve ortak standartlar olmadan kaosa döner, small releases continuous integration olmadan mümkün değildir.

Bir Feature'ın XP ile Akışı

Bookstore'da yeni bir kural geliyor: 500 TL ve üzeri siparişlerde kargo ücretsiz. Mevcut kod her siparişten 49,90 TL sabit ücret alıyor. İşi Ada ve Alan pair olarak alıyor. Ada klavyede, Alan yanında. İlk adım kod değil, test:

public class ShippingFeeTests
{
    [Theory]
    [InlineData(499.99, 49.90)]
    [InlineData(500.00, 0)]
    public void For_AppliesFreeShippingThreshold(decimal subtotal, decimal expected) =>
        Assert.Equal(expected, ShippingFee.For(subtotal));
}

Alan'ın ilk sorusu sınırın kendisi oluyor: "500 dahil mi?" Requirement'ı yazan Product Owner'a mesaj atıyorlar, cevap "dahil" geliyor ve test buna göre yazılıyor. Test-first'ün ilk faydası tam olarak bu: belirsizlik kod yazılmadan önce ortaya çıkıyor. Testi çalıştırıyorlar:

failed Bookstore.Shipping.Tests.ShippingFeeTests.For_AppliesFreeShippingThreshold(subtotal: 500, expected: 0) (1ms)
  Assert.Equal() Failure: Values differ
  Expected: 0
  Actual:   49.90

Test run summary: Failed!
  total: 2
  failed: 1
  succeeded: 1

Kırmızı, beklendiği gibi: 499,99 için mevcut davranış zaten doğru, 500 için yanlış. Testi geçirecek en basit kodu yazıyorlar:

public static decimal For(decimal subtotal) => subtotal >= 500m ? 0m : 49.90m;

Testler yeşile dönüyor ve değişiklik hemen ana hatta, yani trunk'a commit ediliyor. Sonra Alan klavyeyi alıyor ve sihirli sayıları isimlendiriyorlar:

namespace Bookstore.Shipping;

public static class ShippingFee
{
    public const decimal FlatFee = 49.90m;
    public const decimal FreeShippingThreshold = 500m;

    public static decimal For(decimal subtotal) =>
        subtotal >= FreeShippingThreshold ? 0m : FlatFee;
}

Testler yine yeşil; bu da ayrı bir commit. Oturumun sonunda trunk'ın geçmişi şöyle görünüyor; en alttaki commit, sabit ücreti hesaplayan mevcut kod:

$ git log --format='%h %ad %s%n        %(trailers:key=Co-authored-by,valueonly,separator=%x2C )' --date=format:'%H:%M'
e5df4ce 11:59 refactor(shipping): name fee constants
        Alan <alan@bookstore.test>
78d87ca 11:59 feat(shipping): free shipping from 500
        Alan <alan@bookstore.test>
5a5d539 11:58 feat(shipping): flat shipping fee

Pair'in ikinci kişisi commit mesajındaki Co-authored-by trailer'ı ile kayda geçiyor; GitHub bu trailer'ı tanıyıp commit'i iki kişiye birden atfediyor. Her commit küçük, her biri testlerden geçmiş ve her biri ayrı ayrı geri alınabilir. Feature branch açılmadı, pull request iki gün beklemedi; review, pair programming sırasında zaten yapıldı. Ekip yine de trunk'a giden her push için CI'ın yeşil olmasını şart koşuyor.

Akış Angular tarafında da aynı: aynı pair, sepet sayfasında "Ücretsiz kargo" etiketini gösteren component için önce bir component testi yazıyor, sonra kodu. TDD'nin ayrıntılı tekniği, kata'lar ve sınırları ilerideki TDD serisinin, trunk'a sık merge ve pipeline ise CI/CD Temelleri serisinin "CI, Continuous Delivery ve Continuous Deployment: Farkları ve Neden Önemli" yazısının konusu.

Neden Önemli: Flaccid Scrum

Yazının başındaki soruya dönelim. Martin Fowler, Ocak 2009'da "Flaccid Scrum" adlı yazısında aynı durumu anlattı: Scrum'ı benimseyen bazı ekipler bir süre sonra yavaşlıyor, çünkü kod tabanının iç kalitesine dikkat etmiyorlar ve teknik borç her yeni feature'ı pahalılaştırıyor. Fowler'ın tespiti, Scrum'ın bir proje yönetimi framework'ü olduğu ve teknik pratikleri bilerek tanımlamadığıydı; bu boşluk, iç kaliteyi ihmal etmeyi kolaylaştırıyor. Önerisi de netti: Scrum'a başlayan ekipler teknik pratikleri de benimsemeli ve XP'nin pratikleri Scrum'la iyi uyuştuğu için iyi bir başlangıç noktası.

Bookstore ekibinin sorunu da Scrum'da değil, Scrum'ın tanımlamadığı yerdeydi: test yoktu, refactoring hep "sonraki sprint"e kaldı, entegrasyon haftada bir yapılıyordu. Scrum serisinin "Scrum'da Teknik Pratikler: Branching, CI, Feature Flag ve Teknik Borç" yazısı bu boşluğu Scrum içinden ele alıyor.

Ne Zaman Kullanma, Ne Zaman Dikkat Et

Pair programming'i her işe zorlamak kötü bir fikir. Karmaşık bir tasarım kararı, kritik bir bug ya da ekibe yeni katılan birinin alışma süreci pair için çok uygundur. Bir configuration dosyasındaki tek satırlık değişiklik ya da mekanik bir yeniden adlandırma için iki kişinin aynı ekrana bakması israftır. Pair programming yorucudur da; gün boyu kesintisiz pair yapmak, sustainable pace'i çiğner.

Collective code ownership'i ekip olgunluğu olmadan ilan etmek de tehlikeli. Testlerin zayıf olduğu, kod standardının olmadığı ve bilginin birkaç kişide toplandığı bir ekipte "herkes her yeri değiştirebilir" kuralı, herkesin her yeri bozabilmesi demek. Önce test ağını ve ortak standartları kur, sonra sahipliği genişlet.

Test-first her durumda doğru yaklaşım da değil. Cevabın ne olacağını bilmediğin keşif amaçlı bir spike'ta önce test yazmak zor ve çoğu zaman anlamsız; spike'ın kodu zaten atılacak. Öğrendiğini production koduna taşırken test-first'e dön.

Üretimde Dikkat

Trunk'a günde birkaç kez merge etmenin ön koşulu hızlı bir CI. Build ve testler 40 dakika sürüyorsa, geliştiriciler değişikliklerini biriktirmeye başlar ve continuous integration adından ibaret kalır. Bookstore ekibi CI süresini her sprint izliyor ve on dakikayı geçtiğinde bunu teknik borç olarak backlog'a alıyor.

Pair'leri döndür. Hep aynı iki kişinin pair olması, bilgiyi iki kişide hapseder; collective ownership'in faydası ancak pair'ler değiştikçe gelir.

Tamamlanmamış işi trunk'ta tutmanın yolu feature flag. Ücretsiz kargo kuralı kampanya başlangıcından önce merge edilebilir ve flag'in arkasında kapalı bekleyebilir.

Sık Düşülen Tuzaklar

XP'yi Scrum'ın rakibi sanmak yaygın bir tuzak. İkisi farklı katmanlarda çalışır: Scrum işin nasıl planlanıp inspect edileceğini, XP kodun nasıl yazılıp entegre edileceğini anlatır. Birçok ekip Scrum'ın event'lerini XP'nin mühendislik pratikleriyle birlikte kullanır.

İkincisi, test-first'ü coverage hedefiyle karıştırmak. Amaç yüksek bir yüzde değil, her davranış değişikliğinin bir testle başlaması. Coverage'ın ne söylediği ve ne söylemediği Test Stratejisi serisinin coverage yazısında.

Üçüncüsü, pair programming'i "iki kişinin bir işi yavaş yapması" diye ölçmek. Pair'in çıktısı yalnız kod değil; review'ın kendisi, paylaşılan bilgi ve daha az hata. Bunları saymadan yapılan verimlilik hesabı yanıltır.

Dördüncüsü, pratikleri tek tek seçip sistemi kırmak: refactoring yapıp test yazmamak ya da collective ownership ilan edip continuous integration yapmamak.

Küçük Bir Deneme

★☆☆ Yukarıdaki örneği kendi makinende kur ve 500 TL sınırını 499,99'a çekecek bir hata ekle. Hangi test kırılıyor ve mesajı sana ne söylüyor?

★★☆ Bir sonraki küçük feature'ı bir ekip arkadaşınla pair olarak, test-first ve her yeşil testten sonra trunk'a commit ederek yap. Oturum sonunda git log çıktısında kaç commit var ve en büyüğü kaç satır?

★★★ Ekibinin bugün kullandığı XP pratiklerini listele ve her birini "tam", "kısmen" ya da "yok" diye işaretle. Hangi eksik pratik, diğer pratiklerin işe yaramasını engelliyor?

XP, Agile'ın en az yanlış anlaşılan tarafı olabilir, çünkü kodun içinde yaşar. Manifesto'nun geri kalanı için aynı şeyi söylemek zor. Bir sonraki yazıda Agile hakkında en yaygın yanlışlara bakıyoruz: dokümansızlık, plansızlık, "Agile = Scrum" ve ritüellerin değerlerin yerine geçmesi.