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

# Denge Kurmak

Çelişen kalite nitelikleri arasında seçim yapma pratiği: alternatif–nitelik tablosunun bir veri yapısına çevrilmesi, aynı tablonun iki ağırlık kümesiyle puanlanması, ağırlık değiştikçe kazanan alternatifin değişmesinin duyarlılık taramasıyla sayılması ve her ağırlığın kaynağının yazılı olup olmamasının kararın savunulabilirliğine bağlanması.

Önceki konu rolün ne olduğunu ve verilmiş bir kararın ekibe nasıl aktarıldığını tanımladı.
Açıkta kalan şey kararın kendisidir: iki kalite niteliği aynı anda sağlanamadığında hangisinin
seçileceği, seçimin neye dayandığı ve seçim sorgulandığında geriye ne kalacağı.

Niteliklerin birbiriyle çelişebildiği ve bu çelişkinin bir olgu olduğu Sistem Tasarımına Giriş
kursunda ölçüldü; erişilebilirlik ile tutarlılık arasındaki gerilim orada sayılarla gösterildi.
Burada tekrarlanmaz. Bu dersin sorusu gerilimin var olup olmadığı değil, gerilim verilmişken
kararın **nasıl** verildiğidir. Ölçülecek nicelik de budur: bir kararın hangi varsayıma ne kadar
tutunduğu.

## Kararın Nesnesi: Alternatif–Nitelik Tablosu

Through-line bölgesel bir kütüphane ağının yazılım sistemidir. Kurgu bir modeldir; gerçek bir
kurum, ekip ya da ürün anlatılmaz. Modelde on dört şube, merkezde kendi bütçesi olan bir bilgi
işlem birimi, dışarıdan alınmış bir katalog sistemi ve içeride yazılmış ödünç servisleri vardır.

Karar şudur: şubelerin ödünç kayıtlarına erişimi nasıl kurulacak? Dört alternatif ve dört nitelik
tanımlanır (**MP1**; puanlar 1–5 aralığında, büyük olan daha iyidir ve model değerleridir):

- `tek-merkez` — tek yetkili veritabanı, her şube her işlemde merkeze bağlanır.
- `sube-onbellek` — merkez yetkili, her şubede salt-okunur önbellek; yazma merkeze gider.
- `sube-kopya` — her şubede tam kopya, şube işlemi yerelde kapatır, eşitleme sonradan olur.
- `dis-modul` — dışarıdan alınmış katalog sisteminin kendi ödünç modülü kullanılır.

Karar, kafada tutulan bir tercih olduğu sürece ölçülemez. Onu ölçülebilir kılan tek şey bir veri
yapısına çevrilmesidir.

```js
// denge/tablo.mjs — alternatif-nitelik tablosu bir veri yapisi olarak; kurgu bir modeldir
export const NITELIK = ["kesinti-dayanimi", "kayit-tazeligi", "degistirilebilirlik", "isletme-maliyeti"];

// Puanlar 1-5 arasinda, buyuk olan daha iyi (MP1). Kaynaklari derste yazilidir.
export const ALTERNATIF = [
  { ad: "tek-merkez",    puan: [1, 5, 4, 5] },
  { ad: "sube-onbellek", puan: [3, 4, 3, 4] },
  { ad: "sube-kopya",    puan: [5, 2, 2, 2] },
  { ad: "dis-modul",     puan: [4, 3, 1, 3] },
];

export function puanla(agirlik) {
  return ALTERNATIF.map((a) => ({
    ad: a.ad,
    toplam: a.puan.reduce((t, p, i) => t + p * agirlik[i], 0),
  })).sort((x, y) => y.toplam - x.toplam);
}

export const kazanan = (agirlik) => puanla(agirlik)[0].ad;
```

Tabloda hiçbir satır bütün sütunlarda üstün değildir. Ödünleşim tam olarak budur: bir sütunu
yükselten alternatif başka bir sütunu düşürür. Kazananı belirleyen şey artık puanlar değil,
sütunlara verilen ağırlıklardır.

## Aynı Tablo, İki Ağırlık Kümesi

İki uygulama biçimi aynı girdide koşturulur. Birincisi ağırlık sorusunu hiç sormaz ve dört
niteliği eşit sayar — pratikte en sık görülen biçim budur, çünkü ağırlık yazılmadığında öntanımlı
olarak eşit kabul edilmiş olur. İkincisi ağırlıkları açıkça yazar.

```js
// denge/puanla.mjs — ayni tablo iki agirlik kumesiyle: kazanan alternatif degisiyor mu
import { NITELIK, ALTERNATIF, puanla } from "./tablo.mjs";

const KUME = {
  "esit-agirlik": [0.25, 0.25, 0.25, 0.25],
  "yazili-agirlik": [0.50, 0.20, 0.15, 0.15],
};

console.log(`nitelik      : ${NITELIK.join(" ")}`);
for (const a of ALTERNATIF) console.log(`${a.ad.padEnd(13)}: ${a.puan.join("    ")}`);
console.log("");
for (const [ad, w] of Object.entries(KUME)) {
  const s = puanla(w);
  console.log(`${ad.padEnd(15)} w=[${w.join(" ")}]`);
  console.log(`  ${s.map((x) => `${x.ad}=${x.toplam.toFixed(2)}`).join("  ")}`);
  console.log(`  kazanan: ${s[0].ad} (ikinciyle fark ${(s[0].toplam - s[1].toplam).toFixed(2)})`);
}
```

```
nitelik      : kesinti-dayanimi kayit-tazeligi degistirilebilirlik isletme-maliyeti
tek-merkez   : 1    5    4    5
sube-onbellek: 3    4    3    4
sube-kopya   : 5    2    2    2
dis-modul    : 4    3    1    3

esit-agirlik    w=[0.25 0.25 0.25 0.25]
  tek-merkez=3.75  sube-onbellek=3.50  sube-kopya=2.75  dis-modul=2.75
  kazanan: tek-merkez (ikinciyle fark 0.25)
yazili-agirlik  w=[0.5 0.2 0.15 0.15]
  sube-kopya=3.50  sube-onbellek=3.35  dis-modul=3.20  tek-merkez=2.85
  kazanan: sube-kopya (ikinciyle fark 0.15)
```

Aynı puan tablosu, aynı dört alternatif; kazanan `tek-merkez` yerine `sube-kopya` oldu ve
`tek-merkez` sondan birinciliğe düştü. Kararı belirleyen şey alternatiflerin ölçülmüş
nitelikleri değil, ağırlıklardır. Ağırlıklar yazılmadığında karar yine de verilir — eşit ağırlık
da bir ağırlık kümesidir, yalnızca kimse onu seçtiğini söylememiştir.

İki kümedeki fark sütunlarının küçüklüğü de bir bilgidir: 0,25 ve 0,15. Kazanan alternatif
ikincisini yarım puan geride bırakmıyor. Bu, kararın ne kadar sağlam durduğunu sormayı gerektirir.

## Duyarlılık Taraması

Tek bir ağırlık kümesiyle çıkan sonuç bir karar değil, bir örnektir. Kararın ne kadar dayanıklı
olduğu ancak ağırlık uzayı taranarak görülür. Tarama, dört ağırlığın toplamı 1 olacak biçimde
0,05 adımlı bir ızgara üretir ve her noktada kazananı sayar.

```js
// denge/tarama.mjs — duyarlilik taramasi: agirlik degistikce kazanan alternatif degisiyor mu
import { NITELIK, ALTERNATIF, puanla, kazanan } from "./tablo.mjs";

const ADIM = 0.05, N = NITELIK.length, ESIT = 1e-9;
const izgara = [];
(function uret(kalan, biriken) {
  if (biriken.length === N - 1) return izgara.push([...biriken, kalan]);
  for (let p = 0; p <= kalan + ESIT; p += ADIM) uret(kalan - p, [...biriken, p]);
})(1, []);

const kesin = new Map(ALTERNATIF.map((a) => [a.ad, 0]));
let berabere = 0;
for (const w of izgara) {
  const s = puanla(w);
  if (s[0].toplam - s[1].toplam < ESIT) { berabere += 1; continue; }
  kesin.set(s[0].ad, kesin.get(s[0].ad) + 1);
}
console.log(`izgara: adim ${ADIM}, ${izgara.length} agirlik vektoru`);
for (const [ad, k] of [...kesin].sort((a, b) => b[1] - a[1]))
  console.log(`  ${ad.padEnd(13)} tek basina ilk sirada: ${String(k).padStart(4)} vektor (%${(100 * k / izgara.length).toFixed(1)})`);
console.log(`  (ilk iki alternatifin esitlendigi ${berabere} vektor sayilmadi)`);

const SECILEN = [0.50, 0.20, 0.15, 0.15];
const secilenKazanan = kazanan(SECILEN);
const l1 = (a, b) => a.reduce((t, v, i) => t + Math.abs(v - b[i]), 0);
let enYakin = { d: Infinity, w: null, ad: null };
for (const w of izgara) {
  const k = kazanan(w);
  if (k === secilenKazanan) continue;
  const d = l1(w, SECILEN);
  if (d < enYakin.d) enYakin = { d, w, ad: k };
}
console.log(`\nsecilen agirlik [${SECILEN.join(" ")}] -> ${secilenKazanan}`);
console.log(`kirilma mesafesi (L1): ${enYakin.d.toFixed(2)}`);
console.log(`  en yakin farkli vektor [${enYakin.w.map((x) => x.toFixed(2)).join(" ")}] -> ${enYakin.ad}`);

console.log("\ntek agirligi 0.10 oynatinca (kalan uc agirlik oranti korunarak dengelenir):");
for (let i = 0; i < N; i++) {
  const satir = [];
  for (const delta of [-0.10, +0.10]) {
    const yeni = SECILEN.slice();
    yeni[i] = Math.max(0, Math.min(1, yeni[i] + delta));
    const pay = (1 - yeni[i]) / (1 - SECILEN[i]);
    for (let j = 0; j < N; j++) if (j !== i) yeni[j] = SECILEN[j] * pay;
    satir.push(`${delta > 0 ? "+" : ""}${delta.toFixed(2)} -> ${kazanan(yeni)}`);
  }
  const degisti = satir.some((s) => !s.endsWith(secilenKazanan));
  console.log(`  ${NITELIK[i].padEnd(20)} ${satir.join(" , ")}${degisti ? "   <- kazanan degisti" : ""}`);
}
```

```
izgara: adim 0.05, 1771 agirlik vektoru
  tek-merkez    tek basina ilk sirada: 1211 vektor (%68.4)
  sube-kopya    tek basina ilk sirada:  314 vektor (%17.7)
  sube-onbellek tek basina ilk sirada:  220 vektor (%12.4)
  dis-modul     tek basina ilk sirada:    0 vektor (%0.0)
  (ilk iki alternatifin esitlendigi 26 vektor sayilmadi)

secilen agirlik [0.5 0.2 0.15 0.15] -> sube-kopya
kirilma mesafesi (L1): 0.10
  en yakin farkli vektor [0.45 0.20 0.15 0.20] -> sube-onbellek

tek agirligi 0.10 oynatinca (kalan uc agirlik oranti korunarak dengelenir):
  kesinti-dayanimi     -0.10 -> sube-onbellek , +0.10 -> sube-kopya   <- kazanan degisti
  kayit-tazeligi       -0.10 -> sube-kopya , +0.10 -> sube-onbellek   <- kazanan degisti
  degistirilebilirlik  -0.10 -> sube-kopya , +0.10 -> sube-kopya
  isletme-maliyeti     -0.10 -> sube-kopya , +0.10 -> sube-onbellek   <- kazanan degisti
```

Tarama üç ayrı sayı üretiyor ve üçü de karar hakkında farklı şey söylüyor.

**Kazanılan bölge.** Seçilen alternatif `sube-kopya`, 1771 vektörün 314'ünde ilk sırada. Karar,
ağırlık uzayının yüzde 17,7'sinde savunulabilir bir karardır. `tek-merkez` yüzde 68,4 ile en geniş
bölgeyi tutuyor; yani seçilen alternatif "genelde en iyi" olan değil, yazılan ağırlıklar altında
en iyi olandır. Bu iki cümle arasındaki fark, kararın gerekçesinin tamamıdır.

**Kırılma mesafesi.** Seçilen vektörden kazananın değiştiği en yakın noktaya L1 uzaklığı 0,10;
işletme maliyeti ağırlığı 0,15'ten 0,20'ye çıkarıldığında kazanan `sube-onbellek` oluyor. Dört
ağırlığın üçünde 0,10'luk bir oynama kazananı değiştiriyor. Bu bir kusur değil, kararın gerçek
hassasiyetidir; sorun ancak bu hassasiyet bilinmeden karar verildiğinde başlar.

**Hiçbir ağırlıkta kazanmayan alternatif.** `dis-modul` 1771 vektörün hiçbirinde tek başına ilk
sırada değil. Bu sonuç ağırlık tartışmasından bağımsızdır: hangi ağırlık kümesi üzerinde
anlaşılırsa anlaşılsın bu alternatif seçilmeyecektir, çünkü `sube-onbellek` ile `sube-kopya`
birlikte onu her yönden kapatıyor. Toplantıda üzerinde en çok konuşulacak alternatif, tartışmaya
hiç girmeden elenebilir olandır.

## Ağırlığın Kaynağı

Buraya kadar ölçülen her şey ağırlıkların doğru olduğunu varsaydı. Ağırlıkların kendisi nereden
geliyor? Sistem Tasarımına Giriş kursunda kurulan **eşiğin kaynağı** ölçüsü tam olarak bunu
sorar: bir sayı yazıldığında, onun neden o sayı olduğu da yazılmış olmalıdır. Ağırlık da bir
eşiktir; kaynağı yazılmamış ağırlık, kaynağı yazılmamış eşikle aynı boşluğu bırakır.

Aşağıdaki koşum her ağırlığa bir kaynak alanı ekler ve iki şeyi kesiştirir: ağırlığın kaynağı
yazılı mı, ve o ağırlık kazananı değiştirebiliyor mu. Kaynak olarak gösterilen üç kayıt
modelin girdisidir (**MP2**); dördüncü ağırlığın arkasında bir kayıt yoktur.

```js
// denge/kaynak.mjs — her agirligin kaynagi yazili mi, kirilma o agirligin uzerinde mi
import { NITELIK, kazanan } from "./tablo.mjs";

const AGIRLIK = [
  { deger: 0.50, kaynak: "sube aginin kopuk kaldigi sure kaydi (MP2)" },
  { deger: 0.20, kaynak: "odunc kurallarindaki yazili iade toleransi (MP2)" },
  { deger: 0.15, kaynak: "yillik kural degisikligi sayisi kaydi (MP2)" },
  { deger: 0.15, kaynak: null },
];

function oynat(w, i, delta) {
  const yeni = w.slice();
  yeni[i] = Math.max(0, Math.min(1, yeni[i] + delta));
  const pay = (1 - yeni[i]) / (1 - w[i]);
  for (let j = 0; j < w.length; j++) if (j !== i) yeni[j] = w[j] * pay;
  return yeni;
}

function denetle(agirlik) {
  const w = agirlik.map((a) => a.deger);
  const temel = kazanan(w);
  const satir = agirlik.map((a, i) => ({
    ad: NITELIK[i],
    kaynakli: a.kaynak !== null,
    kirilgan: [-0.10, 0.10].some((d) => kazanan(oynat(w, i, d)) !== temel),
  }));
  return { temel, satir, acik: satir.filter((s) => s.kirilgan && !s.kaynakli).length };
}

for (const [ad, agirlik] of [["ilk hali", AGIRLIK],
  ["maliyet agirligi olculdukten sonra", AGIRLIK.map((a, i) =>
    i === 3 ? { deger: 0.25, kaynak: "birim butce tavani ve kopya basina yillik gider (MP3)" }
      : i === 0 ? { deger: 0.40, kaynak: a.kaynak } : a)]]) {
  const d = denetle(agirlik);
  console.log(`${ad}: w=[${agirlik.map((a) => a.deger.toFixed(2)).join(" ")}] -> ${d.temel}`);
  for (const s of d.satir)
    console.log(`  ${s.ad.padEnd(20)} kaynak: ${(s.kaynakli ? "yazili" : "yok").padEnd(7)}` +
      ` kirilgan: ${s.kirilgan ? "evet" : "hayir"}`);
  console.log(`  kazanani degistirebilen ama kaynagi yazilmamis agirlik: ${d.acik}\n`);
}
```

```
ilk hali: w=[0.50 0.20 0.15 0.15] -> sube-kopya
  kesinti-dayanimi     kaynak: yazili  kirilgan: evet
  kayit-tazeligi       kaynak: yazili  kirilgan: evet
  degistirilebilirlik  kaynak: yazili  kirilgan: hayir
  isletme-maliyeti     kaynak: yok     kirilgan: evet
  kazanani degistirebilen ama kaynagi yazilmamis agirlik: 1

maliyet agirligi olculdukten sonra: w=[0.40 0.20 0.15 0.25] -> sube-onbellek
  kesinti-dayanimi     kaynak: yazili  kirilgan: evet
  kayit-tazeligi       kaynak: yazili  kirilgan: hayir
  degistirilebilirlik  kaynak: yazili  kirilgan: hayir
  isletme-maliyeti     kaynak: yazili  kirilgan: hayir
  kazanani degistirebilen ama kaynagi yazilmamis agirlik: 0
```

İlk koşumda kararı taşıyamayan tek bir sayı var: işletme maliyeti ağırlığı hem kazananı
değiştirebiliyor hem de kaynağı yazılmamış. Karar `sube-kopya` yönünde verildi, ama gerekçesinin
bir bacağı boşta. `degistirilebilirlik` ağırlığının kaynağı yazılmış olması ise kararı hiç
sağlamlaştırmıyor — o ağırlık 0,10 oynatıldığında kazanan değişmiyor. Gerekçe yazma emeği,
kararın taşındığı yere değil, taşınmadığı yere harcanmış.

İkinci koşum eksik kaynağın kapatılmasının sonucudur: birim bütçe tavanı ve kopya başına yıllık
gider ölçülünce (**MP3**) maliyet ağırlığı 0,15 yerine 0,25 çıkıyor, kesinti ağırlığı da 0,50'den 0,40'a
iniyor. Kazanan `sube-onbellek` oluyor ve kaynağı yazılmamış kırılgan ağırlık sayısı 1'den 0'a
düşüyor. İlk karar yanlış değildi; ölçülmemişti. İki koşumun farkı, mimarın işinin ağırlıkları
tartışmak değil, ağırlıkların kaynağını bulmak olduğunu gösteriyor.

Buradan çıkan ölçü şudur: **kazananı değiştirebilen ama kaynağı yazılmamış ağırlık sayısı.** Bu
sayı sıfır değilse karar savunulabilir değildir — doğru ya da yanlış olduğu bilinmiyor demektir.
Sayı sıfırsa karar tartışılabilir kalır, ama tartışma artık ağırlık üzerinde değil, ağırlığın
dayandığı kayıt üzerinde yürür ve o kayıt ölçülebilir bir şeydir.

## Özet

- Denge kurmak, tercih beyan etmek değil, alternatif–nitelik tablosunu bir veri yapısına çevirip
  ağırlıklı puanlamayı koşturmaktır; tabloda hiçbir alternatif bütün sütunlarda üstün değildir.
- Aynı dört alternatif ve aynı puanlar, eşit ağırlıkla `tek-merkez`, yazılı ağırlıkla
  `sube-kopya` kazandırdı; ağırlık yazılmadığında eşit ağırlık öntanımlı olarak seçilmiş olur.
- 1771 vektörlük duyarlılık taramasında `sube-kopya` yüzde 17,7'lik bir bölgede kazandı,
  `tek-merkez` yüzde 68,4'lük bölgede; kırılma mesafesi 0,10 ve dört ağırlığın üçünde 0,10'luk
  oynama kazananı değiştiriyor.
- `dis-modul` 1771 vektörün hiçbirinde tek başına ilk sırada değil; ağırlık üzerinde anlaşmaya
  gerek kalmadan elenebilen alternatif, tartışmadan önce elenir.
- Kararın savunulabilirliği tek bir sayıyla ölçülür: kazananı değiştirebilen ama kaynağı
  yazılmamış ağırlık sayısı. İlk koşumda 1, maliyet ağırlığı ölçüldükten sonra 0 ve kazanan
  `sube-onbellek` oldu.

## Sonraki Adım

Denge kurma ölçümü kararın **hangi** alternatife gittiğini verdi, ama seçilen alternatifin
kendisinin ne kadar ağır olduğunu sormadı. `sube-onbellek` seçildiğinde ortaya bir önbellek
katmanı, bir eşitleme yolu ve bir geçersizleştirme kuralı çıkar; her biri sistemin taşıyacağı
yeni bir parçadır. Bir sonraki soru şudur: bu parçaların hangisi işin kendisinden gelir,
hangisi yalnızca çözümün kurulma biçiminden? İkisini ayırmadan yapılan her sadeleştirme, ya
gereken bir şeyi siler ya da hiçbir şeyi silmez. Sonraki ders karmaşıklığı iki bileşene ayırır
ve sadeleştirmenin kaldırabildiği payı, kaldıramadığı paydan sayarak ayırır.
