---
title: 'Tasarım Sistemi Uyarlaması'
source: 'https://academia.sh/tr/kurslar/capraz-platform-uretim/tasarim-sistemi-uyarlamasi'
course: 'Çapraz Platform Üretim Pratiği'
language: tr
updated: '2026-10-21T05:02:51+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Tasarım belirteci, bileşen ve tasarım sistemi arasındaki ilişkiyi açıklar'
    - 'Bir bileşenin platforma göre uyarlanmasının ne kazandırdığını ve neye mal olduğunu karşılaştırır'
    - 'Uyarlanmış bir bileşenin her iki platformda tam çalıştığını ölçer'
    - 'Belirteç değeri değişince işlerlik kaydının aynı kaldığını gösterir'
---

# Tasarım Sistemi Uyarlaması

Tasarım sistemi uyarlaması, tek bir tasarım dilini iki platformun beklentisine göre ayarlar. Ders uyarlanmış bir bileşenin her iki platformda da tam çalıştığını, başka bir bileşenin ise sürüm koşulunda kısıtlı kaldığını ölçer.

Önceki derste platforma göre değişen şey bir yetenekti: katman yeteneği karşılamayınca özellik kapandı. Bu derste platforma göre değişen şey görünümdür. Bir ürünün tek bir tasarım dili vardır; renkleri, aralıkları, köşe yuvarlaklıkları ve yazı ölçüleri ürünün iki platformda da tanınmasını sağlar. Ama iOS ve Android kullanıcıları kendi platformlarından farklı alışkanlıklar getirir ve iyi bir tasarım sistemi bu farkı bilerek uyarlar. Ders önce uyarlamanın nasıl kurulduğunu anlatır, sonra uyarlanmış bir bileşenin işlerliğini ölçer.

## Tasarım Belirteçleri

Tasarım sistemi, bir ürünün görünümünü tutarlı kılan parçalar bütünüdür: belirteçler, bu belirteçlerden kurulan bileşenler ve bileşenlerin ne zaman nasıl kullanılacağını söyleyen yönergeler. **Tasarım belirteci**, bir tasarım kararının adı konmuş değeridir: `accent` bir renk, `gap` bir aralık, `radius` bir köşe yuvarlaklığıdır. Bileşen rengi ya da aralığı kendi içine yazmaz, belirteci adıyla okur. Kazancı tek yerde değişmektir: vurgu rengi belirteçte değişir ve onu okuyan her bileşen ona uyar.

Belirteçler üç katmanda düşünülür. Temel katman ürünün iki platformda da aynı tuttuğu değerleri taşır. Uyarlama katmanı bir platformda temelin üstüne yazılan değerleri taşır. Bileşen son değeri bu ikisinin birleşiminden okur: platformda tanımlı bir değer varsa o, yoksa temel değer. Böylece uyarlama bir istisna listesi olarak küçük kalır; ürünün çoğu değeri hâlâ tek yerde durur.

Aşağıdaki parça bu okumayı bir bileşen üzerinde gösterir. Tarih seçici biçimini ve genişliğini belirteçten alır; hangi platformda koştuğunu kendisi sormaz. Parça ölçülmez.

```jsx
// Platform kodu: belirteci okuyan bilesen
function DatePicker({ tokens, value, onChange }) {
  const Picker = tokens.picker === "tekerlek" ? WheelPicker : CalendarPicker;
  return (
    <Picker
      value={value}
      onChange={onChange}
      width={tokens.width}
      radius={tokens.radius}
    />
  );
}
```

Bileşenin içinde bir platform denetimi yoktur. Hangi biçimin seçileceğine belirteç karar verir ve belirteci platformun uyarlama katmanı doldurur. Bu, önceki dersin katman sınırının görünüm tarafındaki karşılığıdır: bileşen ne istediğini söyler, platformun nasıl karşıladığını bilmez.

## Platforma Göre Uyarlama

Uyarlamanın gerekçesi alışkanlıktır. Tarih seçmek iOS'ta bir tekerleği çevirmek ya da küçük bir takvim açmak olabilir; Android'de bir takvim penceresinde güne dokunmaktır. İki kullanıcı da kendi platformunda bunu bekler. Aynı bileşenin her yerde tek biçimde çıkması ürüne tutarlılık kazandırır ama kullanıcının platformdan getirdiği beklentiyi bozar. Uyarlamak beklentiyi korur, bedelini de ödetir: ekip artık iki biçimi tasarlamak, yapmak ve sınamak zorundadır.

Bu bedel küçümsenmemelidir. Uyarlanan her bileşen bir sınama çarpanıdır: iki platformda iki biçim, iki ayrı genişlik, iki ayrı köşe yuvarlaklığı demektir. Bu yüzden iyi bir tasarım sistemi neyin uyarlanacağını bilinçli seçer. Tarih seçici gibi platformun kendi alışkanlığı güçlü olan bileşenler uyarlanır; markanın kimliğini taşıyan renk ve yazı ölçüleri tek kalır.

Uyarlama yalnız görünüm değildir. Bazı bileşenler platformun sunduğu bir görsel yeteneğe dayanır; bulanık bir arka plan gibi. Bu yetenek her platformda ve her sürümde yoktur. Bileşen bu durumda iki yoldan birini seçer: yeteneği şart koşar ve yoksa çalışmaz, ya da yoksa sade bir arka plana düşer. İkinci yol bir yedektir ve ders bunu sınırlayıcı ölçümün ikinci yarısında ölçer.

## Belirteçten Koşula

Model uyarlamayı iki adımda kurar. Önce belirteçleri bir yardımcı dosyada tutar. Sonra `themeFor(platform)` bir platformun belirteçlerinden koşul üretir: seçicinin biçimi tanımlıysa koşulun `has` listesinde `picker` vardır, bulanık arka plan destekleniyorsa `blur` vardır. Dersin çekirdeği her derste olduğu gibi aşağıda yeniden verilir.

```javascript
// operability.mjs — bir ozelligin bir kosulda ne kadar calistigini siniflandirir
export const LEVELS = ["tam", "kisitli", "ertelenen", "kapali"];
const FALLBACKS = ["kisitli", "ertelenen"];

export function feature(name, needs, fallback = {}) {
  return { name, needs, fallback };
}

export function condition(name, has) {
  return { name, has };
}

function judge(item, cond) {
  const missing = item.needs.filter((need) => !cond.has.includes(need)).sort();
  let level = "tam";
  for (const need of missing) {
    const given = FALLBACKS.includes(item.fallback[need]) ? item.fallback[need] : "kapali";
    if (LEVELS.indexOf(given) > LEVELS.indexOf(level)) level = given;
  }
  return { level, feature: item.name, condition: cond.name, missing };
}

export function assess(features, conditions) {
  const records = [];
  for (const cond of conditions) {
    for (const item of features) records.push(judge(item, cond));
  }
  return records;
}

export function printLevels(records) {
  for (const r of records) {
    const missing = r.missing.length === 0 ? "-" : r.missing.join(",");
    console.log(`${r.level}: ${r.feature} @ ${r.condition} eksik=${missing}`);
  }
}

export function countLevels(records) {
  for (const name of LEVELS) {
    console.log(`${name}: ${records.filter((r) => r.level === name).length}`);
  }
  console.log(`etkilenen: ${records.filter((r) => r.level !== "tam").length}`);
}
```

Dokuz kayıtlık açılış ölçümünün sayısı ilk derste verildi; bu ders onu değiştirmez, yalnız kendi kesitini ölçer. Belirteçler ve `themeFor` ders-yerel bir yardımcı dosyada durur. Üç uyarlama vardır: iOS, Android ve sürüm koşulunu temsil eden eski bir Android.

```javascript
// tokens.mjs — tek tasarim dilinin platforma gore uyarlanan degerleri
import { condition } from "./operability.mjs";

const BASE = { accent: "mavi", gap: 8, radius: 4, blur: true };

const ADAPT = {
  ios: { picker: "tekerlek", radius: 10, width: 280 },
  android: { picker: "takvim", width: 320 },
  "android-legacy": { picker: "takvim", width: 320, blur: false },
};

export function tokensFor(platform) {
  return { ...BASE, ...ADAPT[platform] };
}

export function themeFor(platform, tokens = tokensFor(platform)) {
  const has = [];
  if (tokens.picker) has.push("picker");
  if (tokens.blur) has.push("blur");
  return condition(platform, has);
}
```

İlk ölçüm işlerliği değil belirteçleri basar. İki platformun son değerleri sıralı anahtarlarla yazılır.

```javascript
// main.mjs
import { tokensFor } from "./tokens.mjs";

for (const platform of ["ios", "android"]) {
  const tokens = tokensFor(platform);
  const keys = Object.keys(tokens).sort();
  console.log(`${platform}: ${keys.map((k) => `${k}=${tokens[k]}`).join(" ")}`);
}
```

```text
ios: accent=mavi blur=true gap=8 picker=tekerlek radius=10 width=280
android: accent=mavi blur=true gap=8 picker=takvim radius=4 width=320
```

Uyarlama katmanı yalnız farkı taşır. `accent` ve `gap` iki platformda temelden gelir, `radius` yalnız iOS'ta ezilir, `picker` ve `width` iki platformda da kendi değerini taşır. Değerlerin hepsi dersin kurgusudur ve birim taşımaz.

**PM3.** Belirteç değerleri (`gap`, `radius`, `width`) dersin kurgusudur; gerçek bir tasarım sisteminin ölçüleri değildir. Model belirteçten yalnız iki sonuç çıkarır: seçicinin biçimi tanımlı mı, bulanık arka plan destekleniyor mu. Bileşenin gerçekte nasıl çizildiği, iki biçimin kullanıcıya nasıl hissettirdiği modelde yoktur. Model, bu işlerliğin kuralını kurar; model çerçevenin kendisi değildir.

## Sınırlayıcı Ölçüm

Dersin odak kaydı `DatePicker @ android`'dir. `DatePicker` yalnız `picker` yeteneğine ihtiyaç duyar. Belirteçler iki platformda farklıdır: iOS'ta tekerlek, Android'de takvim. Ama ikisinde de bir seçici biçimi vardır, bu yüzden yetenek iki koşulda da var olur.

```javascript
// main.mjs
import { feature, assess, printLevels } from "./operability.mjs";
import { themeFor } from "./tokens.mjs";

const features = [feature("DatePicker", ["picker"])];
const conditions = [themeFor("ios"), themeFor("android")];
printLevels(assess(features, conditions));
```

```text
tam: DatePicker @ ios eksik=-
tam: DatePicker @ android eksik=-
```

`DatePicker @ android` tamdır. Bu ölçüm M32/K03'ün sorusundan farklıdır. O ders düzen aşamasında bir bileşenin genişliğinin sahibini sordu. Tasarım sistemi bir bileşeni platforma göre uyarladığında genişliği değişebilir; işlerlik genişliği değil, bileşenin o koşulda işini görüp görmediğini sınıflar. İki platformda seçici iki farklı genişlikte, iki farklı biçimde çizilir ve ikisinde de işini görür.

Kuralın belirteç değerlerini görmediğini ikinci ölçüm doğrudan gösterir. Android uyarlamasında köşe yuvarlaklığı, genişlik ve seçicinin biçimi değiştirilir; önceki ve sonraki kayıtlar karşılaştırılır.

```javascript
// main.mjs
import { feature, assess } from "./operability.mjs";
import { tokensFor, themeFor } from "./tokens.mjs";

const features = [feature("DatePicker", ["picker"])];
const before = assess(features, [themeFor("android")]);
const edited = { ...tokensFor("android"), radius: 16, width: 360, picker: "liste" };
const after = assess(features, [themeFor("android", edited)]);
console.log(JSON.stringify(before) === JSON.stringify(after) ? "kayit ayni" : "kayit degisti");
```

```text
kayit ayni
```

Üç belirteç değişti, kayıt aynı kaldı. Kural yalnız `needs`, `fallback` ve `has`'e girenleri görür; yetenek kümesine yansımayan bir değişiklik kaydı bozmaz. Bu bir çelişki değil, ölçünün kendisidir: genişliğin dar ya da geniş olması kullanıcıyı etkileyebilir, ama model yalnız seçicinin işini görüp görmediğini söyler.

İkinci karşılaştırma yedek taşıyan bir bileşendir. `FrostedCard` bulanık bir arka plan ister; bulanıklık yoksa sade arka plana düşer. Bulanıklığı karşılamayan eski bir Android sürümü koşulu eklenir.

```javascript
// main.mjs
import { feature, assess, printLevels } from "./operability.mjs";
import { themeFor } from "./tokens.mjs";

const features = [
  feature("DatePicker", ["picker"]),
  feature("FrostedCard", ["blur"], { blur: "kisitli" }),
];
const conditions = [themeFor("ios"), themeFor("android"), themeFor("android-legacy")];
printLevels(assess(features, conditions));
```

```text
tam: DatePicker @ ios eksik=-
tam: FrostedCard @ ios eksik=-
tam: DatePicker @ android eksik=-
tam: FrostedCard @ android eksik=-
tam: DatePicker @ android-legacy eksik=-
kisitli: FrostedCard @ android-legacy eksik=blur
```

Eski sürüm koşulunda `DatePicker` hâlâ tamdır, `FrostedCard` ise kısıtlıdır: bulanıklık eksiktir, özellik sade arka planla hemen çalışır. Altı kaydın beşi tamdır. Bu sayı açılıştaki 5/1/2/1 ölçümünün sayısı değildir; iki ölçüm farklı kümeleri sayar.

**PM4.** Eski sürüm koşulunun bulanıklığı karşılamadığı dersin kurgusudur. Hangi gerçek sürümün bu yeteneği taşıdığını model söylemez; bu yüzden metinde sürüm numarası yazılmaz. Sade arka planın kullanıcıya ne kadar kötü ya da iyi göründüğü de modelde yoktur.

Yedek, kapalıyı kısıtlıya çeviren tasarım kararıdır. `FrostedCard`'ın `fallback` eşlemi boş olsaydı aynı eksik kapalı sonuç verirdi. Tasarım sistemi bu kararı bileşenin içine yazar: bileşen yeteneği bulamadığında ne yapacağını önceden bilir.

## Özet

- Bu dersin işlerliği: tam. `DatePicker @ android` kaydında seçici iOS'ta tekerlek, Android'de takvim olsa da `picker` yeteneği iki koşulda vardır ve eksik yoktur.
- Tasarım belirteci bir tasarım kararının adı konmuş değeridir; uyarlama katmanı temelin üstüne yalnız platform farkını yazar.
- Genişlik, köşe yuvarlaklığı ve seçici biçimi değişse de kayıt aynı kaldı; kural yetenek kümesine yansımayan değişikliği görmez.
- Bulanıklığı karşılamayan eski sürüm koşulunda `FrostedCard` kısıtlı çıktı, `DatePicker` tam kaldı.
- Uyarlama beklentiyi korur ve sınama çarpanı doğurur; yedek ise kapalıyı kısıtlıya çeviren tasarım kararıdır.

## Sonraki Adım

Bu derste yeteneği belirtecin içeriği belirledi. Sıradaki ders, `Yapılandırma ve Ortam Yönetimi`, yeteneğin yapılandırmadan geldiği durumu ele alır: geliştirme, hazırlık ve üretim ortamları, gizli değerler ve uzaktan yapılandırmaya ulaşılamayan ilk açılışta bir bayrağın değeri.
