---
title: 'Araç Zinciri'
source: 'https://academia.sh/tr/kurslar/tasarim-sistemleri/arac-zinciri'
course: 'Tasarım Sistemleri'
language: tr
updated: '2026-08-17T18:09:34+00:00'
license: 'CC BY-SA 4.0'
---

# Araç Zinciri

Tasarım aracıyla kod arasında tek yönlü doğruluk kaynağı, belirteç dışa aktarımının normalleştirilmesi, sahte farkların elenmesi ve kalan gerçek sapmanın sınıflandırılarak eşitleme oranına bağlanması.

Önceki dersin taraması kod tarafında kaldı: sistem bileşeninin kullanılıp kullanılmadığına
bakıldı, ama o bileşenin taşıdığı değerlerin tasarım kitaplığındakiyle aynı olup olmadığına
bakılmadı. Bir ekip sistem düğmesini kullanıyor olabilir ve düğmenin dolgu rengi tasarım
dosyasındakinden farklı olabilir; kapsam yüzdesi bunu yüzde yüz olarak sayar.

Araç zinciri bu boşluğu kapatır. İşi, tasarım aracındaki değerlerle koddaki değerlerin
aynı olduğunu **sürekli olarak doğrulamaktır**. Bu ders zincirin yönünü tanımlar, fark
raporunu üretir ve raporun okunabilir hâle gelmesi için gereken normalleştirmeyi gösterir.

## Doğruluğun Yönü

Bir değer iki yerde tutuluyorsa, hangisinin doğru olduğu önceden kararlaştırılmalıdır. Üç
düzen vardır ve üçü de tek yönlüdür:

- **Tasarım aracı kaynaktır.** Değerler tasarım kitaplığında tanımlanır, dışa aktarılır ve
  koda üretilir. Kodda elle değişiklik yapılmaz.
- **Kod kaynaktır.** Değerler bir belirteç dosyasında tanımlanır ve tasarım aracına
  aktarılır. Tasarımcı değeri araçta değil dosyada değiştirir.
- **Nötr bir kaynak vardır.** Değerler araçtan da koddan da bağımsız bir dosyada — bir JSON
  belgesinde — tanımlanır; hem tasarım aracı hem kod bu dosyadan beslenir.

Dördüncü bir seçenek olarak görünen **iki yönlü eşitleme** çalışmaz. İki taraf da yazma
yetkisine sahipse, aynı belirtecin iki tarafta birden değişmesi bir çakışma üretir ve
çakışmayı çözecek bir kural yoktur: hangi değerin daha yeni olduğu, hangisinin daha doğru
olduğunu söylemez. Bu yüzden araç zinciri kurulurken verilen ilk karar, hangi yönde
akacağıdır; teknik seçimler bu karardan sonra gelir.

Yön seçildikten sonra zincirin biçimi aynıdır: **dışa aktarım → dönüştürme → hedef
biçimler**. Dönüştürme adımı adları hedefin sözleşmesine çevirir, değerleri hedefin
birimlerine getirir ve türetilmiş belirteçleri hesaplar. Hedef biçimler birden çok olabilir
— aynı kaynaktan CSS özel özellikleri, mobil biçim dosyaları ve belge sayfaları üretilir.

## Fark Raporunun Üretilmesi

Yön ne olursa olsun, iki tarafın aynı olduğunun denetlenmesi gerekir. Denetimin önündeki
asıl engel, iki tarafın **aynı değeri farklı biçimde yazmasıdır**: tasarım aracı rengi
büyük harfli onaltılık yazar, kod küçük harfli; tasarım aracı uzunluğu piksel yazar, kod
kök boyutuna göre oran yazar.

Aşağıdaki program on sekiz tasarım belirteci ile on sekiz kod belirtecini üç aşamada
karşılaştırır: ham hâlde, yalnız adlar normalleştirilerek ve hem adlar hem değerler
normalleştirilerek.

```js
// eslestirme.mjs — tasarim aracindan cikan belirtec disa aktarimi ile koddaki
// belirtec tanimi arasinda fark raporu

// Tasarim aracinin disa aktardigi ad-deger cifleri.
const TASARIM = {
  "Renk/Yüzey/Birincil": "#FFFFFF",
  "Renk/Yüzey/İkincil": "#F7F7F8",
  "Renk/Kenarlık/Varsayılan": "#B7BCC2",
  "Renk/Metin/Birincil": "rgb(31, 35, 40)",
  "Renk/Metin/İkincil": "#5A6169",
  "Renk/Eylem/Ana": "#275EA5",
  "Renk/Eylem/Ana Üzeri": "#FFF",
  "Renk/Eylem/İkincil": "#3B7BC8",
  "Aralık/Adım 1": "4px",
  "Aralık/Adım 2": "8px",
  "Aralık/Adım 3": "12px",
  "Aralık/Adım 4": "16px",
  "Tipografi/Gövde/Boyut": "16px",
  "Tipografi/Gövde/Satır Yüksekliği": "1.5",
  "Tipografi/Başlık/Boyut": "24px",
  "Yuvarlaklık/Küçük": "4px",
  "Yuvarlaklık/Orta": "8px",
  "Gölge/Yükselti 1": "0 1px 2px rgba(0, 0, 0, 0.08)",
};

// Kodda tanimli ozel ozellikler.
const KOD = {
  "--renk-yuzey-birincil": "#ffffff",
  "--renk-yuzey-ikincil": "#f7f7f8",
  "--renk-kenarlik-varsayilan": "#b7bcc2",
  "--renk-metin-birincil": "#1f2328",
  "--renk-metin-ikincil": "#5a6169",
  "--renk-eylem-ana": "#275ea5",
  "--renk-eylem-ana-uzeri": "#ffffff",
  "--renk-eylem-ikincil": "#2f6bb5",
  "--aralik-adim-1": "0.25rem",
  "--aralik-adim-2": "0.5rem",
  "--aralik-adim-3": "0.75rem",
  "--aralik-adim-4": "1rem",
  "--tipografi-govde-boyut": "1rem",
  "--tipografi-govde-satir-yuksekligi": "1.5",
  "--tipografi-baslik-boyut": "1.5rem",
  "--yuvarlaklik-kucuk": "0.25rem",
  "--yuvarlaklik-orta": "0.5rem",
  "--renk-eylem-tehlike": "#a12d2d",
};

// Ad normalizasyonu: 02. dersteki cevriyazim kuralinin aynisi.
const CEVRIM = { "ı": "i", "İ": "i", "ş": "s", "Ş": "s", "ç": "c", "Ç": "c", "ğ": "g", "Ğ": "g", "ü": "u", "Ü": "u", "ö": "o", "Ö": "o" };
const cevir = (s) => [...s].map((h) => CEVRIM[h] ?? h).join("");
const adNormal = (tasarimAdi) => "--" + cevir(tasarimAdi).toLowerCase().replace(/[/\s]+/g, "-");

// Deger normalizasyonu: renk -> alti haneli kucuk harfli onaltilik, uzunluk -> piksel.
const KOK_BOYUT = 16;
function degerNormal(deger) {
  const d = deger.trim().replace(/\s+/g, " ");
  const kisaOnaltilik = d.match(/^#([0-9a-fA-F]{3})$/);
  if (kisaOnaltilik) return "#" + [...kisaOnaltilik[1]].map((h) => h + h).join("").toLowerCase();
  if (/^#[0-9a-fA-F]{6}$/.test(d)) return d.toLowerCase();
  const rgb = d.match(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/);
  if (rgb) return "#" + rgb.slice(1, 4).map((n) => Number(n).toString(16).padStart(2, "0")).join("");
  const rem = d.match(/^(-?[\d.]+)rem$/);
  if (rem) return `${Number(rem[1]) * KOK_BOYUT}px`;
  const px = d.match(/^(-?[\d.]+)px$/);
  if (px) return `${Number(px[1])}px`;
  return d;
}

// Uc asamali karsilastirma: ham, yalniz ad normalizasyonu, tam normalizasyon.
function karsilastir(adDonusum, degerDonusum) {
  const sol = new Map(Object.entries(TASARIM).map(([a, d]) => [adDonusum(a), degerDonusum(d)]));
  const sag = new Map(Object.entries(KOD).map(([a, d]) => [a, degerDonusum(d)]));
  const yalnizTasarim = [...sol.keys()].filter((a) => !sag.has(a));
  const yalnizKod = [...sag.keys()].filter((a) => !sol.has(a));
  const degerFarki = [...sol.entries()].filter(([a, d]) => sag.has(a) && sag.get(a) !== d).map(([a]) => a);
  return { yalnizTasarim, yalnizKod, degerFarki, ortak: sol.size - yalnizTasarim.length };
}

const asamalar = [
  ["ham karşılaştırma", (a) => a, (d) => d],
  ["ad normalizasyonu", adNormal, (d) => d],
  ["ad + değer normalizasyonu", adNormal, degerNormal],
];

console.log("aşama                       ortak ad   yalnız tasarımda   yalnız kodda   değer farkı   toplam fark");
let son = null;
for (const [ad, aD, dD] of asamalar) {
  const s = karsilastir(aD, dD);
  son = s;
  const toplam = s.yalnizTasarim.length + s.yalnizKod.length + s.degerFarki.length;
  console.log(
    `${ad.padEnd(27)} ${String(s.ortak).padStart(8)} ${String(s.yalnizTasarim.length).padStart(18)} ` +
    `${String(s.yalnizKod.length).padStart(14)} ${String(s.degerFarki.length).padStart(13)} ${String(toplam).padStart(13)}`
  );
}

console.log("\n— GERÇEK SAPMALAR —");
for (const a of son.degerFarki) {
  const tasarimAnahtar = Object.keys(TASARIM).find((k) => adNormal(k) === a);
  console.log(`değer farkı: ${a}\n    tasarım: ${TASARIM[tasarimAnahtar]} → ${degerNormal(TASARIM[tasarimAnahtar])}\n    kod    : ${KOD[a]} → ${degerNormal(KOD[a])}`);
}
for (const a of son.yalnizTasarim) console.log(`yalnız tasarımda: ${a} (${TASARIM[Object.keys(TASARIM).find((k) => adNormal(k) === a)]})`);
for (const a of son.yalnizKod) console.log(`yalnız kodda: ${a} (${KOD[a]})`);

// Eslesme orani ve kapi: hangi esikte yayin durdurulur?
const toplamBelirtec = new Set([...Object.keys(TASARIM).map(adNormal), ...Object.keys(KOD)]).size;
const gercekFark = son.yalnizTasarim.length + son.yalnizKod.length + son.degerFarki.length;
console.log(`\ntoplam belirteç (birleşim): ${toplamBelirtec}`);
console.log(`gerçek sapma: ${gercekFark}   eşitleme oranı: %${(((toplamBelirtec - gercekFark) / toplamBelirtec) * 100).toFixed(1)}`);
```

```
aşama                       ortak ad   yalnız tasarımda   yalnız kodda   değer farkı   toplam fark
ham karşılaştırma                  0                 18             18             0            36
ad normalizasyonu                 17                  1              1            16            18
ad + değer normalizasyonu         17                  1              1             1             3

— GERÇEK SAPMALAR —
değer farkı: --renk-eylem-ikincil
    tasarım: #3B7BC8 → #3b7bc8
    kod    : #2f6bb5 → #2f6bb5
yalnız tasarımda: --golge-yukselti-1 (0 1px 2px rgba(0, 0, 0, 0.08))
yalnız kodda: --renk-eylem-tehlike (#a12d2d)

toplam belirteç (birleşim): 19
gerçek sapma: 3   eşitleme oranı: %84.2
```

## Sahte Farkın Elenmesi

Üç aşamalı tablo, fark raporunun neden çoğu kuruluşta okunmadığını açıklıyor. Ham
karşılaştırmada 36 fark var ve bunların **hiçbiri gerçek değil**; iki taraf yalnızca farklı
yazım sözleşmeleri kullanıyor. Böyle bir rapor bir kez okunur, sonra kapatılır.

Ad normalizasyonu farkı 18'e indiriyor. Kullanılan kural, ikinci derste kurulan çevriyazım
kuralının aynısıdır; adlandırma sözleşmesinin bedeli orada ödenmişti, karşılığı burada
alınıyor. Sözleşme olmasaydı bu adım için ayrı bir eşleme tablosu tutulması gerekirdi ve
tablo, belirteç eklendikçe eskirdi.

Değer normalizasyonu farkı 3'e indiriyor. Elenen 15 fark üç ayrı biçim ayrımından
doğuyordu: onaltılık gösterimin harf büyüklüğü, üç haneli kısa gösterim, `rgb` işlevsel
gösterimi ve uzunluk biriminin piksel yerine kök oranı olarak yazılması. Bunların hiçbiri
görsel bir sapma üretmez; ikisi de aynı rengi ve aynı uzunluğu anlatır.

Sıralamanın kendisi bir tasarım kararıdır: normalizasyon **karşılaştırmadan önce** yapılır,
sonra değil. Farkı önce hesaplayıp sonra elemeye çalışmak, hangi farkın sahte olduğunu her
seferinde yeniden karar vermek demektir.

## Kalan Üç Sapmanın Okunması

Geriye kalan üç satırın her biri farklı bir iş üretir.

**Değer farkı** — `--renk-eylem-ikincil` iki tarafta farklı. Bu, doğruluk kaynağının
ihlalidir: taraflardan biri diğerini beklemeden değiştirilmiş. Kaynağın yönü belirlenmiş
olsa bile bu satır tek başına hangi tarafın haklı olduğunu söylemez; söylediği şey, akışın
bir yerde kırıldığıdır. Bu rengin ikincil eylem rengi olduğu ve tipografi ve renk
derslerinde birincil eylem rengiyle arasındaki kontrast oranının hesaplandığı düşünülürse,
sapmanın sonucu görsel değil işlevsel olabilir.

**Yalnız tasarımda** — `--golge-yukselti-1` tasarım kitaplığında var, kodda yok.
Gerçekleştirilmemiş bir tasarım kararıdır ve katkı sürecine bir iş olarak girer. Bu satırın
raporda kalması, kararın unutulmasını önler.

**Yalnız kodda** — `--renk-eylem-tehlike` kodda var, tasarımda yok. Bir ekip yıkıcı bir
eylem için renk gerektiğinde belirteci kod tarafında eklemiş. Bu satır iki sonuçtan birine
bağlanır: ya belirteç meşrudur ve tasarım kitaplığına eklenir, ya da değildir ve
kaldırılır. Kararsız bırakıldığında belirteç kalır, kullanılır ve bir sonraki tema
türetiminde karşılığı bulunamaz.

Eşitleme oranı — yüzde 84,2 — bu üç satırın tek sayıya indirilmiş hâlidir ve ikinci derste
ad eşleşmesi için kurulan kapı burada da kurulabilir: oran bir alt sınırın altına
düştüğünde yayın durdurulur. Sayının kendisinden çok, **her yayında ölçülüyor olması**
önemlidir; sapma bir olay değil, biriken bir niceliktir.

## Zincirin Kapsayamadığı Katman

Araç zincirinin yapabildiği ile yapamadığı arasındaki sınır nettir ve bu ders boyunca
kurulan yapının neden yalnız araçla kurulamayacağını açıklar.

Zincir **değerleri** eşitler: renk, aralık, tipografi, yuvarlaklık, gölge. Bunlar ad-değer
çiftleridir, makinede karşılaştırılabilir ve otomatik üretilebilir.

Zincir **davranışı** eşitleyemez. Bir düğmenin hangi durumda hangi rengi aldığı, bir kip
pencerenin odağı nereye götürdüğü, bir açılır listenin klavyeyle nasıl gezildiği tasarım
aracından dışa aktarılamaz. Bu katman, ikinci derste kurulan adlandırma sözleşmesiyle,
üçüncü derste tanımlanan belge bölümleriyle ve beşinci derste kurulan inceleme kapılarıyla
eşitlenir. Araç zinciri belirteç katmanının bekçisidir; bileşen katmanının bekçisi
yönetişimdir.

## Özet

- Bir değer iki yerde tutuluyorsa doğruluk kaynağının yönü önceden kararlaştırılmalıdır;
  iki yönlü eşitleme, çözülemeyen çakışmalar ürettiği için bir seçenek değildir. Zincirin
  biçimi yönden bağımsızdır: dışa aktarım, dönüştürme ve birden çok hedef biçim.
- Fark raporu normalleştirme olmadan okunmaz hâle gelir; örnekte 36 farkın 33'ü yalnızca
  yazım sözleşmesi ayrımından doğan sahte farktı.
- Normalizasyon karşılaştırmadan önce yapılır; ad kuralı adlandırma sözleşmesinden
  devralınır, değer kuralı renkleri tek gösterime ve uzunlukları tek birime indirir.
- Kalan sapmalar üç sınıftır: değer farkı akışın kırıldığını, yalnız tasarımda olan
  gerçekleştirilmemiş bir kararı, yalnız kodda olan kayıtsız eklenmiş bir belirteci gösterir.
- Eşitleme oranı her yayında ölçülür ve bir alt sınıra bağlanır; sapma bir olay değil,
  biriken bir niceliktir.
- Araç zinciri değerleri eşitler, davranışı eşitleyemez; bileşen katmanının eşitliği
  adlandırma sözleşmesi, belge bölümleri ve inceleme kapılarıyla sağlanır.

## Kurs Kapanışı

Bu konu, tasarım sisteminin değerlerden sonra gelen katmanını kurdu. Kataloğa neyin gireceği
bir kapsam ölçütüne, giren şeyin ne kadar hazır olduğu olgunluk düzeylerinin çıkış
koşullarına bağlandı. Tasarımla kod arasındaki ortak dil bir türetim kuralı hâline getirildi
ve eşleşmeyen adlar sayıldı. Belgelendirme yedi zorunlu bölüme ayrıldı ve kapsamı kullanımla
ağırlıklandırılarak hesaplandı. Sürüm numarası bir tartışma konusu olmaktan çıkarılıp
arayüz farkının sonucuna dönüştürüldü, göç maliyeti çağrı yeriyle ölçüldü. Katkı akışı bir
durum makinesi oldu, yönetişim modelleri kuyruk ve sapma sayılarıyla karşılaştırıldı,
benimseme depo taramasıyla ölçüldü ve son olarak belirteç katmanının eşitliği bir fark
raporuna bağlandı.

Bütün bu yapının ortak yanı, her kararın bir sayıya bağlanmış olmasıdır: kapsam yüzdesi,
eksik etkisi, göç maliyeti, kuyruk süresi, sapma sayısı, eşitleme oranı. Bir tasarım
sisteminin başarısı bu sayılarla izlenir; izlenmediğinde sistem, kimsenin ne zaman
bıraktığını fark etmediği bir kütüphaneye dönüşür.

Katalog kuruldu ve yönetiliyor. Ancak kataloğun her kaydı hâlâ bir soruyu yanıtsız
bırakıyor: bu bileşen klavyeyle nasıl kullanılır, odağı nereye götürür, ekran okuyucuya
kendini nasıl bildirir? Üçüncü derste "erişilebilirlik notu" bir belge bölümü olarak
tanımlandı ve kararlı olgunluk düzeyinin çıkış ölçütlerinden biri sayıldı, ama o notun
içine ne yazılacağı söylenmedi. Bir sonraki kurs olan **Erişilebilir Bileşen Kalıpları**
bu boşluğu doldurur: düğmeden açılır listeye, sekmelerden kip pencereye kadar kataloğun her
bileşeninin klavye davranışını, odak yönetimini ve ekran okuyucuya bildirdiği bilgiyi tek
tek belirtir; karmaşık etkileşim kalıplarının odak tuzaklarını tasarlar ve arayüz metniyle
yerelleştirme gereksinimlerini sistemin parçası hâline getirir.
