---
title: 'Karar Verme'
source: 'https://academia.sh/tr/kurslar/mimarin-rolu/karar-verme'
course: 'Mimarın Rolü'
language: tr
updated: '2026-08-17T18:10:32+00:00'
license: 'CC BY-SA 4.0'
---

# Karar Verme

Geri döndürülebilir ve geri döndürülemez kararların ayrı yöntemle verilmesi: geri alma maliyetinin bir bağımlılık kümesinden hesaplanması, aynı karar kümesinin bu maliyete göre iki sınıfa ayrılması, hızlı deneme ile uzun değerlendirme yöntemlerinin her iki sınıfta koşturulması ve bekleme süresi ile yanlış karar maliyetinin dört politika üzerinde karşılaştırılması.

Önceki ders bir sadeleştirmenin fiyatını hesapladı ama bir soruyu açıkta bıraktı: kaldırılan
sarmalayıcı geri getirilebilir mi? Altı modüle dağılmış ayar okumasını yeniden tek noktada
toplamak, sarmalayıcıyı kaldırmakla aynı büyüklükte bir iş değildir. Kararların bir kısmı
böyledir; geri alınması, verilmesinden kat kat pahalıdır.

Bu fark pratikte çoğu zaman görülmez, çünkü bütün kararlar aynı yerde ve aynı hızda verilir.
Sonuç iki yönlü bir israftır: geri alınabilir kararlar için haftalarca toplantı yapılır, geri
alınamaz kararlar bir öğleden sonra kapatılır. Bu dersin ölçtüğü şey, bu iki hatanın kaç adam-güne
mal olduğudur.

## Geri Alma Maliyeti Bir Bağımlılık Kümesinden Okunur

Bir kararın ne kadar geri döndürülebilir olduğu bir his değil, bir hesaptır. Karar bir bileşene
iner; geri almak o bileşeni ve ona bağlı olan her bileşeni dolaşmayı gerektirir. Model kütüphane
ağının yazılım sistemidir; kurgudur, gerçek bir kurum anlatılmaz.

```js
// karar/maliyet.mjs — geri alma maliyeti bir bagimlilik kumesinden okunur; kurgu bir modeldir
// BAGIMLILIK[x] = x'in kullandigi bilesenler. Geri alma, degisen bileseni ve ona bagli
// olan her bileseni dolasmayi gerektirir (MP7).
export const BAGIMLILIK = {
  "veri-deposu": [],
  "odunc-cekirdegi": ["veri-deposu"],
  "uyelik": ["veri-deposu"],
  "katalog-kapisi": ["veri-deposu"],
  "ayirtma": ["odunc-cekirdegi"],
  "raporlama": ["veri-deposu", "odunc-cekirdegi"],
  "odeme-kapisi": ["odunc-cekirdegi"],
  "bildirim": ["ayirtma"],
  "eslesme-hatti": ["katalog-kapisi", "veri-deposu"],
  "sube-istemcisi": ["odunc-cekirdegi", "ayirtma", "katalog-kapisi"],
};

// MP7 katsayilari (adam-gun). Bilesen basina dolasma 2; yazilmis kayitlarin bicimi degistiyse
// goc 15; disa acilmis bir arayuz surumlenmisse esgudum 20.
export const KATSAYI = { bilesen: 2, goc: 15, sozlesme: 20 };

export const KARAR = [
  { ad: "odunc-kaydi-bicimi", bilesen: "veri-deposu", bicim: true, disa: false },
  { ad: "sube-istemcisi-onbellegi", bilesen: "sube-istemcisi", bicim: false, disa: false },
  { ad: "katalog-kapisi-surumu", bilesen: "katalog-kapisi", bicim: false, disa: true },
  { ad: "bildirim-metni-sablonu", bilesen: "bildirim", bicim: false, disa: false },
  { ad: "raporlama-sorgu-plani", bilesen: "raporlama", bicim: false, disa: false },
  { ad: "odunc-kural-motoru", bilesen: "odunc-cekirdegi", bicim: false, disa: false },
  { ad: "ayirtma-siralama-kurali", bilesen: "ayirtma", bicim: false, disa: false },
  { ad: "odeme-arayuzu-surumu", bilesen: "odeme-kapisi", bicim: false, disa: true },
];

export function dolasilan(bilesen) {
  const kume = new Set([bilesen]);
  let buyudu = true;
  while (buyudu) {
    buyudu = false;
    for (const [x, kullandiklari] of Object.entries(BAGIMLILIK))
      if (!kume.has(x) && kullandiklari.some((y) => kume.has(y))) { kume.add(x); buyudu = true; }
  }
  return kume;
}

export const geriAlma = (k) => dolasilan(k.bilesen).size * KATSAYI.bilesen +
  (k.bicim ? KATSAYI.goc : 0) + (k.disa ? KATSAYI.sozlesme : 0);
```

Hesabın üç bileşeni var ve üçü de farklı bir olguyu sayıyor. Dolaşılan bileşen sayısı grafikten
okunur ve kararın nereye indiğine bağlıdır. Kayıt biçimi değiştiyse geri alma yalnız kodu değil,
yazılmış kayıtları da ilgilendirir; bu pay koda dokunmadan da orada durur. Dışa açılmış bir arayüz
sürümlendiyse geri alma tek taraflı yapılamaz, karşı tarafla eşgüdüm gerekir.

## İki Sınıf

```js
// karar/sinifla.mjs — geri alma maliyeti hesaplanir, kararlar iki sinifa ayrilir
import { KARAR, dolasilan, geriAlma } from "./maliyet.mjs";

// MP8: esik, bir surum dongusunde geri alma icin ayrilabilen kapasitedir: 10 adam-gun.
const ESIK = 10;
console.log("karar                     | bilesen          | dolasilan | goc | disa | geri alma");
console.log("--------------------------|------------------|-----------|-----|------|----------");
for (const k of KARAR)
  console.log(`${k.ad.padEnd(25)} | ${k.bilesen.padEnd(16)} | ` +
    `${String(dolasilan(k.bilesen).size).padStart(9)} | ${(k.bicim ? "var" : "  -").padStart(3)} | ` +
    `${(k.disa ? "var" : "  -").padStart(4)} | ${String(geriAlma(k)).padStart(9)}`);

const sinif = (k) => (geriAlma(k) <= ESIK ? "dondurulebilir" : "dondurulemez");
const grup = { dondurulebilir: [], dondurulemez: [] };
for (const k of KARAR) grup[sinif(k)].push(k);
console.log(`\nesik ${ESIK} adam-gun (MP8)`);
for (const [ad, liste] of Object.entries(grup))
  console.log(`  geri ${ad.padEnd(15)}: ${liste.length} karar, maliyetler ` +
    `${liste.map(geriAlma).join(", ")} (toplam ${liste.reduce((t, k) => t + geriAlma(k), 0)})`);
```

```
karar                     | bilesen          | dolasilan | goc | disa | geri alma
--------------------------|------------------|-----------|-----|------|----------
odunc-kaydi-bicimi        | veri-deposu      |        10 | var |    - |        35
sube-istemcisi-onbellegi  | sube-istemcisi   |         1 |   - |    - |         2
katalog-kapisi-surumu     | katalog-kapisi   |         3 |   - |  var |        26
bildirim-metni-sablonu    | bildirim         |         1 |   - |    - |         2
raporlama-sorgu-plani     | raporlama        |         1 |   - |    - |         2
odunc-kural-motoru        | odunc-cekirdegi  |         6 |   - |    - |        12
ayirtma-siralama-kurali   | ayirtma          |         3 |   - |    - |         6
odeme-arayuzu-surumu      | odeme-kapisi     |         1 |   - |  var |        22

esik 10 adam-gun (MP8)
  geri dondurulebilir : 4 karar, maliyetler 2, 2, 2, 6 (toplam 12)
  geri dondurulemez   : 4 karar, maliyetler 35, 26, 12, 22 (toplam 95)
```

Sekiz kararın dördü **geri döndürülebilir karar**, dördü **geri döndürülemez karardır** ve toplam
geri alma maliyetinin 95'i, yani yüzde 88,8'i dört kararda toplanmış. Sayıların dağılımı da
öğreticidir: `odeme-arayuzu-surumu` yalnız tek bir bileşene iniyor, dolaşılan bileşen sayısı 1,
ama dışa açılmış bir arayüz sürümlendiği için maliyeti 22. `odunc-kural-motoru` altı bileşene
yayılıyor ama geri alması 12. Yani "kaç yere dokunuyor" tek başına sınıfı belirlemiyor; kararı
geri döndürülemez yapan şey çoğu zaman dokunduğu yer sayısı değil, dışarıya verdiği söz ya da
yazdığı kayıttır.

## İki Yöntem, İki Sınıf

Karşılaştırma iki karar yöntemini aynı karar kümesinde koşturur. **Hızlı deneme** kararı iki günde
verir ve yanlış çıkma oranı yüksektir; **uzun değerlendirme** on beş gün bekletir ve yanlış çıkma
oranı düşüktür. İki yöntem iki ayrı maliyeti üretir: bekleyen her gün gecikme bedeli yazar, yanlış
çıkan her karar geri alma maliyetini yazar.

```js
// karar/yontem.mjs — iki karar yontemi iki sinifta: bekleme suresi ve yanlis karar maliyeti
import { KARAR, geriAlma } from "./maliyet.mjs";

// MP9: hizli deneme 2 gun bekletir ve kararlarin %35'i geri alinir; uzun degerlendirme
// 15 gun bekletir ve %10'u geri alinir. Bekleyen her gun 0.4 adam-gun gecikme bedeli yazar.
const YONTEM = {
  "hizli-deneme": { bekleme: 2, yanlis: 0.35 },
  "uzun-degerlendirme": { bekleme: 15, yanlis: 0.10 },
};
const GUNLUK = 0.4, ESIK = 10;
const beklenen = (y, toplamGeriAlma, adet) =>
  y.bekleme * adet * GUNLUK + y.yanlis * toplamGeriAlma;

const grup = { dondurulebilir: [], dondurulemez: [] };
for (const k of KARAR) grup[geriAlma(k) <= ESIK ? "dondurulebilir" : "dondurulemez"].push(k);

console.log("sinif           | karar | geri alma | hizli-deneme | uzun-degerlendirme | kazanan");
console.log("----------------|-------|-----------|--------------|--------------------|--------");
for (const [ad, liste] of Object.entries(grup)) {
  const t = liste.reduce((s, k) => s + geriAlma(k), 0);
  const h = beklenen(YONTEM["hizli-deneme"], t, liste.length);
  const u = beklenen(YONTEM["uzun-degerlendirme"], t, liste.length);
  console.log(`${ad.padEnd(15)} | ${String(liste.length).padStart(5)} | ${String(t).padStart(9)} | ` +
    `${h.toFixed(2).padStart(12)} | ${u.toFixed(2).padStart(18)} | ${h < u ? "hizli" : "uzun"} (fark ${Math.abs(h - u).toFixed(2)})`);
}

const a = YONTEM["hizli-deneme"], b = YONTEM["uzun-degerlendirme"];
const kirilma = (b.bekleme - a.bekleme) * GUNLUK / (a.yanlis - b.yanlis);
console.log(`\nyontem kirilma noktasi: geri alma maliyeti ${kirilma.toFixed(1)} adam-gunu asinca` +
  ` uzun degerlendirme ucuzlar`);
console.log(`sinif esigi (MP8) ${ESIK}, kirilma noktasi ${kirilma.toFixed(1)}: iki sayi ayni degil`);

const politika = {
  "hepsine-hizli": () => "hizli-deneme",
  "hepsine-uzun": () => "uzun-degerlendirme",
  "esige-gore": (k) => (geriAlma(k) <= ESIK ? "hizli-deneme" : "uzun-degerlendirme"),
  "kirilmaya-gore": (k) => (geriAlma(k) <= kirilma ? "hizli-deneme" : "uzun-degerlendirme"),
};
console.log("\npolitika        | bekleme (gun) | beklenen maliyet (adam-gun)");
console.log("----------------|---------------|----------------------------");
for (const [ad, sec] of Object.entries(politika)) {
  let gun = 0, maliyet = 0;
  for (const k of KARAR) {
    const y = YONTEM[sec(k)];
    gun += y.bekleme;
    maliyet += y.bekleme * GUNLUK + y.yanlis * geriAlma(k);
  }
  console.log(`${ad.padEnd(15)} | ${String(gun).padStart(13)} | ${maliyet.toFixed(2).padStart(27)}`);
}
```

```
sinif           | karar | geri alma | hizli-deneme | uzun-degerlendirme | kazanan
----------------|-------|-----------|--------------|--------------------|--------
dondurulebilir  |     4 |        12 |         7.40 |              25.20 | hizli (fark 17.80)
dondurulemez    |     4 |        95 |        36.45 |              33.50 | uzun (fark 2.95)

yontem kirilma noktasi: geri alma maliyeti 20.8 adam-gunu asinca uzun degerlendirme ucuzlar
sinif esigi (MP8) 10, kirilma noktasi 20.8: iki sayi ayni degil

politika        | bekleme (gun) | beklenen maliyet (adam-gun)
----------------|---------------|----------------------------
hepsine-hizli   |            16 |                       43.85
hepsine-uzun    |           120 |                       58.70
esige-gore      |            68 |                       40.90
kirilmaya-gore  |            55 |                       38.70
```

İlk tablo dersin çekirdeğidir. Aynı iki yöntem, aynı ölçütle, iki sınıfta ters sonuç veriyor. Geri
döndürülebilir sınıfta hızlı deneme 17,80 adam-gün daha ucuz; geri döndürülemez sınıfta uzun
değerlendirme 2,95 adam-gün daha ucuz. Yöntemlerden biri ötekinden iyi değildir; sınıfa
yanlış eşleştirilen yöntem kötüdür.

İki farkın büyüklüğü de eşit değil. Geri döndürülebilir kararlarda yanlış yöntemin cezası 17,80,
geri döndürülemez kararlarda 2,95. Yani geri alınabilir bir karar için uzun değerlendirme
yapmanın bedeli, geri alınamaz bir karar için hızlı denemenin bedelinden bu modelde daha
büyüktür — çünkü uzun değerlendirmenin gecikme bedeli her karar için ödenir, geri alma maliyeti
ise ancak karar yanlış çıkarsa.

## Eşiğin Kaynağı Yeniden

Alt tablo dört politikayı aynı sekiz karar üzerinde koşturuyor. `hepsine-uzun` politikası hem en
pahalı hem en yavaş: 58,70 adam-gün ve 120 gün bekleme. `hepsine-hizli` en hızlısı, 16 gün, ama
maliyeti sınıfa göre ayıran politikalardan yüksek. İki sınıfı ayırmak, bekleme süresini
`hepsine-uzun` politikasına göre 52 gün kısaltırken maliyeti de 17,80 adam-gün düşürüyor.

Ama iki eşik arasında bir uyuşmazlık var ve bu, ilk dersteki **eşiğin kaynağı** ölçüsünün burada
karşımıza çıkışıdır. Sınıf eşiği 10 adam-gün olarak alındı; kaynağı bir sürüm döngüsünde geri alma
için ayrılabilen kapasiteydi. Yöntem kırılma noktası ise 20,8 adam-gün: bu sayı seçilmedi,
yöntemlerin bekleme süresi ve yanlışlık oranından türetildi. İkisi aynı olmadığı için
`esige-gore` politikası `odunc-kural-motoru` kararını (geri alma 12) uzun değerlendirmeye
gönderiyor, oysa o karar kırılma noktasının altında. `kirilmaya-gore` politikası aynı kararı hızlı
denemeye gönderiyor ve hem 13 gün hem 2,20 adam-gün kazanıyor.

Buradan çıkan kural, sınıflandırmanın kendisinden daha dar ve daha kullanışlıdır: **sınıf eşiği
yöntemden türetilir, seçilmez.** İki karar yönteminin bekleme süresi ve yanlışlık oranı yazıldığı
anda eşik hesaplanabilir hale gelir. Kapasite gibi başka bir yerden gelen sayı eşik olarak
kullanıldığında sınıflandırma yine bir şey kazandırır, ama kazandırabileceğinin altında kalır.

## Özet

- Bir kararın geri alma maliyeti histen değil bağımlılık kümesinden okunur: dolaşılan bileşen
  sayısı, yazılmış kayıtların göçü ve dışa açılmış arayüzün eşgüdümü.
- Sekiz kararlık kümede toplam geri alma maliyetinin yüzde 88,8'i dört geri döndürülemez kararda
  toplandı; dolaşılan bileşen sayısı tek başına sınıfı belirlemiyor.
- Aynı iki yöntem iki sınıfta ters sonuç verdi: geri döndürülebilir sınıfta hızlı deneme 17,80,
  geri döndürülemez sınıfta uzun değerlendirme 2,95 adam-gün daha ucuz.
- Dört politika aynı küme üzerinde koşturulunca `hepsine-uzun` hem en pahalı hem en yavaş çıktı
  (58,70 adam-gün, 120 gün); sınıfa göre ayıran politika 40,90 adam-gün ve 68 güne indi.
- Sınıf eşiği 10, yöntem kırılma noktası 20,8 idi; eşiği kırılma noktasından türeten politika
  38,70 adam-gün ve 55 gün ile dördünün en iyisi oldu.
- Eşik seçilmez, iki yöntemin bekleme süresi ve yanlışlık oranından hesaplanır.

## Sonraki Adım

Buraya kadar ölçülen her şey mimarın masasında bitiyor: ağırlık, karmaşıklık payı, geri alma
maliyeti, eşik. Sekiz kararın hiçbiri o masada uygulanmıyor. `odunc-kaydi-bicimi` kararının geri
alma maliyeti 35 adam-gün olarak hesaplandı, ama bu sayının anlamı bütçeyi tutan birimde
farklıdır, kayıt göçünü yapacak ekipte farklıdır, şubede iş yapan görevlide bambaşkadır. Hesap
aynı kalır, karşı tarafın onu okuma biçimi değişir. Sonraki ders teknik olmayan muhataplarla
kurulan iletişimi bir veri yapısına çevirir: aynı karar iki ayrı anlatımla aynı paydaşlara
sunulduğunda sorulan soru ve onay için gereken tur sayılır.
