---
title: Komut
source: 'https://academia.sh/tr/kurslar/tasarim-kaliplari/komut'
course: 'Tasarım Kalıpları'
language: tr
updated: '2026-08-17T18:10:38+00:00'
license: 'CC BY-SA 4.0'
---

# Komut

Gönderi üzerindeki işlemlerin doğrudan çağrı olarak yazılması ile nesneye çevrilmesinin karşılaştırılması: geri alınabilen işlem sayısı, denetim izi kaydı sayısı, izi doğrudan sürümde üretmek için düzenlenen işlem gövdesi sayısı ve ortaya çıkan ortak bağlaşım, kalıbın bedeli olarak dosya sayısı ile çağrı derinliği.

Gözlemci olmuş bir şeyi haber veriyordu: bildirim gönderildiği anda durum çoktan değişmişti ve
geri dönüş yoktu. Kitaplığın operatör tarafında tersi isteniyor. Bir gönderiye indirim
uygulanması, rotasının değiştirilmesi ve iptali operatör kararıyla yapılıyor; yanlış uygulanan
bir işlemin geri alınması gerekiyor. Bugün bu üç işlem doğrudan alan değiştiren çağrılardır ve
çağrı bittiğinde eski değer kaybolmuştur.

**Komut** (command) kalıbı, bir işlemi çağrı olmaktan çıkarıp nesne yapar: ne yapılacağı ve
hangi parametreyle yapılacağı bir nesnenin içinde durur, çağrılmadan önce elde tutulabilir,
sıraya konabilir, kaydedilebilir ve tersi aynı nesneden istenebilir. Ölçülecek sayılar geri
alınabilen işlem sayısı, denetim izi kaydı sayısı ve kesişen bir iş eklendiğinde düzenlenen
işlem gövdesi sayısıdır. Bedel tarafında dosya sayısı ve çağrı derinliği durur.

## Alan Nesnesi ve İki Düzen

Alan nesnesi iki sürümde ortaktır. Her yazma işleminde kendi dosyalarımıza ait çağrı
çerçevesi sayısını kaydeder; bu sayı dolaylılık basamağının koşumdaki karşılığıdır.

```sh
mkdir -p dogrudan komut
```

```js
// gonderi.mjs — alan nesnesi; her yazma isleminde cagri derinligini kaydeder
export const gonderi = (kod) => {
  const durum = { kod, indirim: 0, rota: "R1", iptal: "hayir" };
  const derinlikler = [];
  return {
    durum,
    derinlikler,
    yaz(alan, deger) {
      durum[alan] = deger;
      derinlikler.push(new Error().stack.split("\n").filter((s) => s.includes(".mjs:")).length);
    },
    ozet: () => `${durum.kod} indirim=${durum.indirim} rota=${durum.rota} iptal=${durum.iptal}`,
  };
};
```

Birinci düzen üç işlemi üç işlev olarak yazar. Bir işlemin tersi hiçbir yerde tanımlı değildir;
`indirimUygula` çağrıldıktan sonra eski oranı bilen kimse kalmaz.

```js
// dogrudan/islem.mjs — islemler alani dogrudan yazar, tersi yoktur
export const indirimUygula = (g, oran) => g.yaz("indirim", oran);
export const rotaDegistir = (g, rota) => g.yaz("rota", rota);
export const iptalEt = (g) => g.yaz("iptal", "evet");
```

İkinci düzende her işlem bir nesne üretir. Nesne, uygulanmadan önceki değeri kendi
kapanışında saklar ve `geriAl` yöntemiyle onu geri yazar.

```js
// komut/indirim.mjs
export const indirimKomutu = (oran) => {
  let onceki;
  return {
    ad: `indirim(${oran})`,
    uygula(g) {
      onceki = g.durum.indirim;
      g.yaz("indirim", oran);
    },
    geriAl(g) {
      g.yaz("indirim", onceki);
    },
  };
};
```

```js
// komut/rota.mjs
export const rotaKomutu = (rota) => {
  let onceki;
  return {
    ad: `rota(${rota})`,
    uygula(g) {
      onceki = g.durum.rota;
      g.yaz("rota", rota);
    },
    geriAl(g) {
      g.yaz("rota", onceki);
    },
  };
};
```

```js
// komut/iptal.mjs
export const iptalKomutu = () => {
  let onceki;
  return {
    ad: "iptal",
    uygula(g) {
      onceki = g.durum.iptal;
      g.yaz("iptal", "evet");
    },
    geriAl(g) {
      g.yaz("iptal", onceki);
    },
  };
};
```

Üç nesnenin ortak sözleşmesi `ad`, `uygula` ve `geriAl` üçlüsüdür. Bu sözleşme, komutu
çalıştıran nesnenin komutun ne yaptığını bilmeden onu yönetmesine yeter. Çalıştırıcı geçmiş
yığıtını tutar ve her çağrıyı denetim izine yazar.

```js
// komut/calistirici.mjs — istemleri calistirir, gecmis yigitini ve denetim izini tutar
export const calistirici = () => {
  const gecmis = [];
  const iz = [];
  return {
    iz,
    calistir(komut, g) {
      komut.uygula(g);
      gecmis.push([komut, g]);
      iz.push(`uygula  ${komut.ad}`);
    },
    geriAl(adet) {
      let sayi = 0;
      while (sayi < adet && gecmis.length > 0) {
        const [komut, g] = gecmis.pop();
        komut.geriAl(g);
        iz.push(`geri-al ${komut.ad}`);
        sayi += 1;
      }
      return sayi;
    },
  };
};
```

## Beş İşlem, Üç Geri Alma

Sürücü betik aynı beş işlemi iki sürüme de uygular, sonra üçünü geri almayı dener ve son
durumları karşılaştırır.

```js
// kosum.mjs — bes islem uygulanir, ucu geri alinir; iki surum karsilastirilir
import { gonderi } from "./gonderi.mjs";
import { indirimUygula, rotaDegistir, iptalEt } from "./dogrudan/islem.mjs";
import { indirimKomutu } from "./komut/indirim.mjs";
import { rotaKomutu } from "./komut/rota.mjs";
import { iptalKomutu } from "./komut/iptal.mjs";
import { calistirici } from "./komut/calistirici.mjs";

const a = gonderi("GN-7");
indirimUygula(a, 10);
rotaDegistir(a, "R2");
indirimUygula(a, 15);
rotaDegistir(a, "R3");
iptalEt(a);
console.log(`dogrudan  bes islem sonrasi : ${a.ozet()}`);
console.log(`dogrudan  geri alinan islem : 0`);

const b = gonderi("GN-7");
const k = calistirici();
for (const komut of [indirimKomutu(10), rotaKomutu("R2"), indirimKomutu(15), rotaKomutu("R3"), iptalKomutu()]) {
  k.calistir(komut, b);
}
console.log(`komut     bes islem sonrasi : ${b.ozet()}`);
const geri = k.geriAl(3);
console.log(`komut     geri alinan islem : ${geri}`);
console.log(`komut     geri alma sonrasi : ${b.ozet()}`);
console.log(`cagri derinligi (dogrudan/komut): ${a.derinlikler[0]} / ${b.derinlikler[0]}`);
console.log(`denetim izi kaydi (dogrudan/komut): 0 / ${k.iz.length}`);
```

```
dogrudan  bes islem sonrasi : GN-7 indirim=15 rota=R3 iptal=evet
dogrudan  geri alinan islem : 0
komut     bes islem sonrasi : GN-7 indirim=15 rota=R3 iptal=evet
komut     geri alinan islem : 3
komut     geri alma sonrasi : GN-7 indirim=10 rota=R2 iptal=hayir
cagri derinligi (dogrudan/komut): 3 / 4
denetim izi kaydi (dogrudan/komut): 0 / 8
```

İki satır ölçümün geçerlilik koşulunu veriyor: beş işlem sonrası iki sürümün özeti birebir
aynı. Sonrası kazançtır. Geri alınan işlem sayısı 0'a karşı 3; geri alma sonrası durum,
ilk iki işlemin uygulandığı duruma birebir dönmüş. Denetim izi 0'a karşı 8 kayıt taşıyor —
beş uygulama ve üç geri alma. Bu sekiz kayıt için hiçbir işlem gövdesine dokunulmadı; kayıt,
komutun `ad` alanını okuyan çalıştırıcıda üretildi.

Çağrı derinliği bedeli veriyor: 3'e karşı 4. Bu sayılar kendi dosyalarımıza ait çağrı
çerçevelerini sayar; taban değer koşum betiğinin çerçevesini de içerdiği için mutlak sayı
önemli değil, iki sürüm arasındaki bir basamak farkı önemlidir. Operatör isteminden alan
yazmasına giden yol bir çağrı uzadı.

## Denetim İzini Doğrudan Sürüme Eklemek

Sekiz kayıtlık izi doğrudan sürümde de üretmek istenirse üç işlem gövdesinin de düzenlenmesi
gerekir; kaydın tutulacağı yer de bir modül düzeyi dizi olmak zorundadır, çünkü üç işlevin
paylaşacağı başka bir yer yoktur.

```js
// denetim.mjs — denetim izini iki surume de ekler ve degisimi olcer
import { cpSync, readFileSync, writeFileSync } from "node:fs";

cpSync("dogrudan", "dogrudan-yeni", { recursive: true });
writeFileSync(
  "dogrudan-yeni/islem.mjs",
  `// dogrudan/islem.mjs — islemler alani dogrudan yazar, tersi yoktur
export const iz = [];
export const indirimUygula = (g, oran) => {
  iz.push(\`uygula  indirim(\${oran})\`);
  g.yaz("indirim", oran);
};
export const rotaDegistir = (g, rota) => {
  iz.push(\`uygula  rota(\${rota})\`);
  g.yaz("rota", rota);
};
export const iptalEt = (g) => {
  iz.push("uygula  iptal");
  g.yaz("iptal", "evet");
};
`,
);
console.log(`duzenlenen islem govdesi = ${(readFileSync("dogrudan-yeni/islem.mjs", "utf8").match(/iz\.push/g) ?? []).length}`);
console.log(`yeni modul duzeyi paylasilan durum = ${(readFileSync("dogrudan-yeni/islem.mjs", "utf8").match(/^export const iz = \[\];$/m) ?? []).length}`);
console.log(`komut surumunde duzenlenen islem govdesi = 0`);
```

```
duzenlenen islem govdesi = 3
yeni modul duzeyi paylasilan durum = 1
komut surumunde duzenlenen islem govdesi = 0
```

Üç gövdeye karşı sıfır gövde. Sayının yanında bir de tür farkı var: doğrudan sürüme eklenen
`iz` dizisi modül düzeyinde paylaşılan değiştirilebilir durumdur, yani tasarım ilkeleri
kursunda en güçlü biçim olarak ölçülen **ortak bağlaşım**. Üç işlev bu diziyi birlikte
değiştirir; ikinci bir iz gerektiğinde ya da testte izin sıfırlanması gerektiğinde üçü birlikte
etkilenir. Komut sürümünde iz çalıştırıcı örneğine aittir, her koşum kendi izini taşır ve
paylaşılan modül durumu sayısı sıfır kalır.

## Bedelin Sayımı

```sh
echo "dosya sayisi: dogrudan=$(ls dogrudan | wc -l | tr -d ' ')  komut=$(ls komut | wc -l | tr -d ' ')"
echo "tersini bilen dosya: dogrudan=0  komut=$(grep -l '^    geriAl(g) {$' komut/*.mjs | wc -l | tr -d ' ')"
echo "gecmis yigitini tutan dosya: komut=$(grep -l 'gecmis.push' komut/*.mjs | wc -l | tr -d ' ')"
```

```
dosya sayisi: dogrudan=1  komut=4
tersini bilen dosya: dogrudan=0  komut=3
gecmis yigitini tutan dosya: komut=1
```

Bir dosyaya karşı dört dosya. Kalıbın bedeli işlem başına bir dosya ve bir tiptir; kazancı ise
işlem sayısından bağımsızdır, çünkü geçmiş yığıtını tutan yer tektir. Dördüncü bir işlem
eklendiğinde bedel bir dosya artar, geri alma ve denetim izi ise kendiliğinden çalışır. Üç
satır bir de sınırı gösteriyor: tersini bilen dosya sayısı işlem sayısına eşit olmak zorundadır,
yani tersi tanımlanamayan bir işlem varsa kalıp geri alma kazancını vermez.

## Özet

- Komut kalıbı bir işlemi nesneye çevirir; nesne ne yapılacağını, parametresini ve tersini
  taşır, bu yüzden uygulanmadan önce tutulabilir ve sonradan geri alınabilir.
- Aynı beş işlem iki sürümde birebir aynı durumu üretti; geri alınan işlem sayısı 0'a karşı 3
  çıktı ve geri alma sonrası durum ilk iki işlemin durumuna birebir döndü.
- Denetim izi komut sürümünde 8 kayıt üretti ve bunun için hiçbir işlem gövdesi düzenlenmedi;
  aynı izi doğrudan sürümde üretmek 3 gövdenin düzenlenmesini ve 1 modül düzeyi paylaşılan
  durumu, yani ortak bağlaşımı gerektirdi.
- Bedel: dosya sayısı 1'den 4'e çıktı, çağrı derinliği 3'ten 4'e yükseldi; tersini bilen dosya
  sayısı işlem sayısına eşit olmak zorundadır.
- Kalıbın kazancı işlem sayısından bağımsızdır, bedeli işlem sayısıyla doğrusal büyür.

## Sonraki Adım

Üç komut aynı üç adımı aynı sırayla yapıyor: önceki değeri sakla, yeni değeri yaz, kaydı
tut. Sıra her komutta aynı, yalnız ortadaki adım değişiyor. Aynı tekrar kitaplığın ücret
hesaplama tarafında daha büyük ölçekte var: yurt içi, yurt dışı ve ekspres taşıyıcı için
ücretlendirme altı adımdan geçiyor ve üç dosya bu altı adımı ayrı ayrı sıralıyor. Sıraya bir
adım eklendiğinde üç dosya da düzenleniyor. Sonraki ders yinelenen satır sayısını ve adım
sırası değiştiğinde düzenlenen dosya sayısını ölçer, sonra iskeleti tek yere alıp aynı
sayıları yeniden hesaplar.
