---
title: Varlıklar
source: 'https://academia.sh/tr/kurslar/alan-odakli-tasarim/varliklar'
course: 'Alan Odaklı Tasarım'
language: tr
updated: '2026-08-17T18:10:41+00:00'
license: 'CC BY-SA 4.0'
---

# Varlıklar

Kimlikle tanımlanan nesnelerin seçim ölçütü: on iki gönderinin değer eşitliğiyle kaç ayrı örneğe indiğinin sayılması, fatura okumasının kaçının doğru çıktığının ölçülmesi, tartım düzeltmesinden sonra aynı kimliği gösteren anahtar sayısının çıkarılması ve iki eşitlik tanımının alanın iki sorusuna verdiği yanıtların karşılaştırılması.

Önceki dersin birleşik sürümünde gönderi üç alan taşıyan düz bir kayıttı ve iki gönderi
ancak alanları eşitse aynı sayılabiliyordu. Alanda bu doğru değildir. Aynı gönderinin
ağırlığı tartım düzeltmesiyle değişir ve gönderi hâlâ aynı gönderidir; iki ayrı gönderinin
bütün alanları eşit olabilir ve ikisi hâlâ iki gönderidir.

Bu ayrımı taşıyan nesneye **varlık nesnesi** (entity) denir: alanları değişse bile aynı
kalan, dolayısıyla eşitliği alanlarıyla değil bir **kimlikle** tanımlanan nesne. Tanım
Nesneye Dayalı Programlamaya Giriş kursunda verilmişti; buradaki iş tanım değil **seçim
ölçütüdür** — hangi alan kavramına kimlik verilir, verilmediğinde ne kaybedilir.

## İki Soru

Ölçüt iki soruya indirgenir. Birincisi: bu şey, alanları değiştikten sonra da aynı şey
midir? İkincisi: bütün alanları eşit olan iki tanesi ayrı ayrı izlenmek zorunda mıdır?

Gönderi ücretlendirme kitaplığında ikisinin de yanıtı evettir. Bir müşteri aynı gün aynı
bölgeye aynı ağırlıkta beş koli gönderir; beşine beş ayrı fatura kesilir. Aynı koli
tartıldığında beyan ağırlığı düzeltilir; fatura o koliye kesilmeye devam eder.

## İki Model

Birinci sürüm gönderiyi alanlarıyla tanımlar. Eşitlik, alanların birleşiminden üretilen bir
anahtardır.

```sh
mkdir -p degerle kimlikle
```

```js
// degerle/gonderi.mjs — kimliksiz gonderi: esitlik alanlarin esitligidir
export const gonderi = (musteri, agirlik, bolge) => ({ musteri, agirlik, bolge });
export const anahtar = (g) => `${g.musteri}|${g.agirlik}|${g.bolge}`;
export const esitMi = (a, b) => anahtar(a) === anahtar(b);
export const agirligiDuzelt = (g, yeniAgirlik) => ({ ...g, agirlik: yeniAgirlik });
```

İkinci sürüm gönderiye bir numara verir. Eşitlik yalnız o numaraya bakar; ağırlık düzeltmesi
nesneyi değiştirir ama kimliğine dokunmaz.

```js
// kimlikle/gonderi.mjs — varlik nesnesi: esitlik gonderi numarasinin esitligidir
export class Gonderi {
  constructor(gonderiNo, musteri, agirlik, bolge) {
    this.gonderiNo = gonderiNo;
    this.musteri = musteri;
    this.agirlik = agirlik;
    this.bolge = bolge;
  }
  anahtar() { return this.gonderiNo; }
  aynisiMi(o) { return o instanceof Gonderi && o.gonderiNo === this.gonderiNo; }
  agirligiDuzelt(yeniAgirlik) { this.agirlik = yeniAgirlik; return this; }
}
```

## Ölçüm

Ölçünün girdisi on iki gönderi ve her birine kesilmiş bir faturadır. Beş gönderi aynı
müşteriye, aynı ağırlığa ve aynı bölgeye aittir; iki tanesi başka bir müşteride, iki tanesi
üçüncü müşterinin ağır kolilerinde tekrarlanır.

```js
// kayitlar.mjs — ucretlendirme baglaminda 12 gonderi ve her birine kesilen fatura
export const KAYITLAR = [
  ["G-1041", "ARC", 2.4, "34", "F-9001"],
  ["G-1042", "ARC", 2.4, "34", "F-9002"],
  ["G-1043", "ARC", 2.4, "34", "F-9003"],
  ["G-1044", "ARC", 2.4, "34", "F-9004"],
  ["G-1045", "ARC", 2.4, "34", "F-9005"],
  ["G-1046", "ARC", 5, "34", "F-9006"],
  ["G-1047", "BKM", 0.8, "06", "F-9007"],
  ["G-1048", "BKM", 0.8, "06", "F-9008"],
  ["G-1049", "BKM", 12, "65", "F-9009"],
  ["G-1050", "CTS", 0.8, "06", "F-9010"],
  ["G-1051", "CTS", 18, "65", "F-9011"],
  ["G-1052", "CTS", 18, "65", "F-9012"],
];
```

Her sürümde fatura tablosu, gönderinin o sürümdeki anahtarıyla kurulur. Sonra ilk gönderinin
ağırlığı 2,4'ten 3,1 kilograma düzeltilir ve tablo yeniden okunur.

```js
// kimlik-olc.mjs — 12 gonderi kac ornekle temsil ediliyor, fatura okumasi kaci dogru
import { KAYITLAR } from "./kayitlar.mjs";
import * as deger from "./degerle/gonderi.mjs";
import { Gonderi } from "./kimlikle/gonderi.mjs";

function olc(ad, kur, anahtar, duzelt) {
  const nesneler = KAYITLAR.map(([no, m, a, b]) => kur(no, m, a, b));
  const tablo = new Map();
  nesneler.forEach((n, i) => tablo.set(anahtar(n), KAYITLAR[i][4]));
  const dogru = nesneler.filter((n, i) => tablo.get(anahtar(n)) === KAYITLAR[i][4]).length;
  console.log(`${ad}: 12 gonderi -> ${tablo.size} ayri ornek`);
  console.log(`  fatura okumasi dogru ${dogru}/12`);

  const eski = anahtar(nesneler[0]);
  const yeni = duzelt(nesneler[0], 3.1);
  tablo.set(anahtar(yeni), tablo.get(eski));
  nesneler[0] = yeni;
  const dogru2 = nesneler.filter((n, i) => tablo.get(anahtar(n)) === KAYITLAR[i][4]).length;
  const isaret = [...tablo.keys()].filter((k) => k === eski || k === anahtar(yeni)).length;
  console.log(`  tartim duzeltmesi sonrasi: tablo girdisi ${tablo.size}, ` +
    `G-1041'i gosteren anahtar ${isaret}`);
  console.log(`  duzeltme sonrasi fatura okumasi dogru ${dogru2}/12`);
}

olc("degerle", (no, m, a, b) => deger.gonderi(m, a, b), deger.anahtar,
  (g, a) => deger.agirligiDuzelt(g, a));
olc("kimlikle", (no, m, a, b) => new Gonderi(no, m, a, b), (g) => g.anahtar(),
  (g, a) => g.agirligiDuzelt(a));

const [ilk, ikinci] = [deger.gonderi("ARC", 2.4, "34"), deger.gonderi("ARC", 2.4, "34")];
const [v1, v2] = [new Gonderi("G-1041", "ARC", 2.4, "34"), new Gonderi("G-1042", "ARC", 2.4, "34")];
console.log(`iki ayri gonderi esit mi -> degerle ${deger.esitMi(ilk, ikinci)}, ` +
  `kimlikle ${v1.aynisiMi(v2)}`);
const v1b = new Gonderi("G-1041", "ARC", 3.1, "34");
console.log(`duzeltilmis gonderi ayni mi -> degerle ` +
  `${deger.esitMi(ilk, deger.agirligiDuzelt(ilk, 3.1))}, kimlikle ${v1.aynisiMi(v1b)}`);
```

```sh
node kimlik-olc.mjs
```

```
degerle: 12 gonderi -> 6 ayri ornek
  fatura okumasi dogru 6/12
  tartim duzeltmesi sonrasi: tablo girdisi 7, G-1041'i gosteren anahtar 2
  duzeltme sonrasi fatura okumasi dogru 6/12
kimlikle: 12 gonderi -> 12 ayri ornek
  fatura okumasi dogru 12/12
  tartim duzeltmesi sonrasi: tablo girdisi 12, G-1041'i gosteren anahtar 1
  duzeltme sonrasi fatura okumasi dogru 12/12
iki ayri gonderi esit mi -> degerle true, kimlikle false
duzeltilmis gonderi ayni mi -> degerle false, kimlikle true
```

İlk sayı kaybın büyüklüğünü veriyor: değer eşitliğiyle on iki gönderi altı örneğe iniyor.
Altı gönderi bir başkasının anahtarına çöktüğü için fatura okumasının yarısı yanlış çıkıyor
— altı gönderi kendisine kesilmeyen faturayı gösteriyor.

İkinci sayı ters yönde bozulmayı gösteriyor. Ağırlık düzeltmesi değer sürümünde yeni bir
anahtar üretiyor; eski anahtar silinemez, çünkü ona bağlı başka gönderiler var. Sonuçta tablo
yedi girdiye çıkıyor ve tek bir gönderi iki anahtarla gösterilir hâle geliyor. Kimlik
sürümünde aynı düzeltme tablo boyunu değiştirmiyor: anahtar `G-1041` kalıyor, on iki okumanın
on ikisi doğru.

Son iki satır ölçütü tek cümleye indiriyor. Alanın birinci sorusu "bu iki gönderi aynı mı"
sorusudur ve yanıtı hayırdır; değer eşitliği evet der. İkinci soru "düzeltilmiş gönderi aynı
gönderi mi" sorusudur ve yanıtı evettir; değer eşitliği hayır der. İki tanımdan biri alanın
iki sorusuna da yanlış, öteki ikisine de doğru yanıt veriyor.

## Kimlik Nereden Gelir

Kimliğin taşıdığı tek şart, nesnenin yaşamı boyunca değişmemesi ve başka hiçbir nesnede
tekrarlanmamasıdır. Alanda hazır bir kimlik varsa o kullanılır: gönderi numarası, sözleşme
numarası, vergi kimlik numarası. Yoksa bir tane üretilir ve üretim kuralı alanın değil
uygulamanın kararıdır.

Alandan gelen bir alan kimlik gibi kullanıldığında ölçü bozulur. Ücretlendirme bağlamında
müşteri ile bölgenin birleşimi çoğu zaman tek bir gönderiyi verir; "çoğu zaman" bir kimlik
ölçütü değildir ve yukarıdaki ölçüm o varsayımın bedelini gösteriyor. Aynı sebeple ağırlık,
posta kodu ve beyan değeri gibi düzeltilebilen alanlar kimliğin parçası olamaz.

Kimliğin ikinci sonucu tekilliktir: aynı kimliğe sahip iki örnek bellekte aynı anda
bulunuyorsa hangisinin doğru olduğu belirsizleşir. Bu sorun Tasarım Kalıpları kursundaki
Kimlik Haritası dersinde ele alınmıştı; varlık nesnesi kararı o kalıbın önkoşuludur, çünkü
tekilliği koruyacak bir kimlik olmadan haritanın anahtarı da yoktur.

## Ne Zaman Kimlik Gerekmez

Ölçütün iki sorusu da hayırsa nesne varlık nesnesi değildir. Kitaplıkta bunun açık bir örneği
bölge katsayısıdır: 1,35 katsayısı ile bir başka 1,35 katsayısı arasında ayrım yoktur ve
katsayının bir yaşam öyküsü de yoktur. Aynı şey ağırlık, para tutarı ve indirim oranı için de
geçerlidir.

Bu kavramlara kimlik verilmesi ölçüyü ters yönde bozar. Bir katsayıya numara verildiğinde
eşitlik karşılaştırması kimliğe bakar ve alanda eşit olan iki değer kodda eşit çıkmaz.
Kimlik, taşıdığı yerde kazanç üretir; taşımadığı yerde her karşılaştırmaya bir kural ekler.

## Özet

- Varlık nesnesi, alanları değiştiği hâlde aynı kalan ve eşitliği bir kimlikle tanımlanan
  nesnedir; seçim ölçütü iki sorudur — alanları değişince aynı mı kalıyor, alanları eşit olan
  ikisi ayrı ayrı izleniyor mu.
- Değer eşitliğiyle on iki gönderi altı örneğe indi; fatura okumasının 6'sı yanlış çıktı.
- Tartım düzeltmesi değer sürümünde tabloyu yedi girdiye çıkardı ve tek gönderiyi iki
  anahtarla gösterdi; kimlik sürümünde tablo on iki girdide kaldı, on iki okuma doğru çıktı.
- Değer eşitliği alanın iki sorusuna da yanlış, kimlik eşitliği ikisine de doğru yanıt verdi.
- Kimlik yaşam boyunca değişmeyen ve tekrarlanmayan bir ad olmalıdır; düzeltilebilen alanlar
  kimliğin parçası olamaz.
- İki sorunun ikisi de hayırsa kimlik gerekmez; katsayı, ağırlık ve oran gibi kavramlara
  kimlik vermek her karşılaştırmaya gereksiz bir kural ekler.

## Sonraki Adım

Bu dersin son bölümü kimlik gerektirmeyen kavramları saydı ama onları hâlâ çıplak sayı ve
katar olarak tuttu: ağırlık bir `number`, bölge bir `string`. O zaman ağırlıkla hacmi
toplamak, kilogramla gramı karşılaştırmak ve kuruşla lirayı çarpmak kodun izin verdiği
işlemler olur. Sonraki ders bu kavramları kendi tipleri hâline getirir, değerle
karşılaştırmanın kaç yerde elle yazıldığını sayar ve birim karışmasının kaç durumda sessizce
yanlış tutar ürettiğini ölçer.
