---
title: 'Tek Parça Mimari'
source: 'https://academia.sh/tr/kurslar/mimari-bicemler/tek-parca-mimari'
course: 'Mimari Biçemler'
language: tr
updated: '2026-08-17T18:10:35+00:00'
license: 'CC BY-SA 4.0'
---

# Tek Parça Mimari

Aynı kitaplığın iki bağlamının tek dağıtım birimi olarak yayınlanması: bir teklif isteğinin geçtiği sınır sayısının, serileştirme noktasının ve sınırdan geçen baytın sayılması, tek dosyalık bir değişikliğin yeniden yayınlattığı dosya sayısının ölçülmesi ve süreci sonlandıran bir kusurun her iki bağlamı birden düşürdüğünün gösterilmesi.

Önceki konu birimlerin birbiriyle nasıl konuştuğunu ele aldı. Her etkileşim biçeminde aynı üç
şey ölçüldü: birimin karşı tarafı bilme yükümlülüğü, bağlanma yönü ve sınırdan geçen veri.
Ancak bütün bu ölçümler bir soruyu sormadan geçti. İstemci ile sunucu, yayımcı ile abone, boru
ile süzgeç — bunların hepsi tek bir çalışan programın içinde de kurulabilir. Yayımla–abone ol
düzeni için ikinci bir süreç gerekmez; bir olay veriyolu nesnesi yeter.

Bu konu o sorunun kendisini sorar: **yazılım kaç ayrı parça olarak yayınlanır?** Cevap etkileşim
biçeminden bağımsızdır ve kendi ölçüleri vardır. Bir **dağıtım birimi** (deployment unit)
birlikte yayınlanmak zorunda olan dosya kümesidir; bir sürüm çıkarıldığında bu kümenin tamamı
aynı anda yerine geçer. **Tek parça mimari** (monolithic architecture) bütün bağlamları tek bir
dağıtım biriminde tutan biçemdir: kaç modül olduğu değişir, dağıtım birimi sayısı 1'dir.

## İki Bağlam, Tek Süreç

Kitaplığın iki sınırlı bağlamı var. Ücretlendirme bağlamında gönderi fiyatlanabilir bir
birimdir; teslimat operasyonu bağlamında rotası ve taşıyıcısı olan fiziksel bir pakettir. Her
ikisi de derli biçimde şöyledir.

```js
// ortak/ucret.mjs — ucretlendirme baglami: gonderi fiyatlanabilir birimdir
export const TARIFE = { kademe: [[1, 3000], [5, 4800], [20, 9600]], bolge: { "34": 100, "06": 115, "35": 125 }, asgari: 2500 };

export function taban(agirlik, bolge) {
  const kademe = TARIFE.kademe.find(([k]) => agirlik <= k) ?? [0, 9600];
  return Math.max(TARIFE.asgari, Math.round((kademe[1] * TARIFE.bolge[bolge]) / 100));
}

export function net(agirlik, bolge, sozlesmeOrani) {
  const t = taban(agirlik, bolge);
  return t - Math.round(t * Math.min(sozlesmeOrani, 0.4));
}
```

```js
// ortak/operasyon.mjs — teslimat operasyonu baglami: gonderi rotali fiziksel pakettir
export const AGAC = { "34": ["34"], "06": ["34", "06"], "35": ["34", "41", "35"] };

export function rota(bolge) { return AGAC[bolge] ?? ["34"]; }

export function tasiyici(bolge) { return rota(bolge).length > 2 ? "MT" : "AN"; }

export function teslimGunu(bolge) { return rota(bolge).length; }
```

Sınır geçişlerini saymak için birimlerin dış yüzü sarılır. Bu sarmalayıcı kurs boyunca aynı
kalır: hangi biçem ölçülüyorsa geçişleri o toplar.

```js
// ortak/sar.mjs — bir modulun dis yuzunu sarar; her cagri birim adiyla kayda gecer
export function sar(ad, modul, kayit) {
  const yuz = {};
  for (const [k, v] of Object.entries(modul)) {
    yuz[k] = typeof v === "function" ? (...a) => { kayit.push(`${ad}.${k}`); return v(...a); } : v;
  }
  return yuz;
}
```

Teklif isteği iki bağlama birden dokunur: net ücret ücretlendirmeden, teslim günü ve taşıyıcı
operasyondan gelir. Tek parça düzende bu birleştirme bir fonksiyon çağrısıdır.

```js
// tek-parca/uygulama.mjs — iki baglam ayni surecte, ayni bellekte, tek dagitim birimi
import * as ucretModul from "../ortak/ucret.mjs";
import * as operasyonModul from "../ortak/operasyon.mjs";
import { sar } from "../ortak/sar.mjs";

export function uygulama(kayit) {
  const ucret = sar("ucret", ucretModul, kayit);
  const operasyon = sar("operasyon", operasyonModul, kayit);
  return {
    teklif(g) {
      kayit.push("uygulama.teklif");
      return {
        id: g.id,
        net: ucret.net(g.agirlik, g.bolge, g.oran),
        gun: operasyon.teslimGunu(g.bolge),
        tasiyici: operasyon.tasiyici(g.bolge),
      };
    },
  };
}
```

## İsteğin ve Yayının Ölçülmesi

Ölçüm iki cinsten sayı çıkarır. Birincisi koşumdan gelir: bir isteğin dokunduğu birim, geçtiği
sınır, serileştirme noktası ve sınırdan geçen bayt. İkincisi dosyalardan gelir: dağıtım
biriminin ithal kapanışı, yani birlikte yayınlanmak zorunda olan dosya kümesi.

```js
// tek-parca/olc.mjs — bir istegin dokundugu birim, gectigi sinir, yayin kumesi ve komsu gereksinimi
import { readFileSync } from "node:fs";
import { dirname, join, normalize } from "node:path";
import { uygulama } from "./uygulama.mjs";

const kayit = [];
const cikti = uygulama(kayit).teklif({ id: "G1", agirlik: 4, bolge: "35", oran: 0.15 });
const birim = new Set(kayit.map((c) => c.split(".")[0]));
console.log(`teklif ciktisi = ${JSON.stringify(cikti)}`);
console.log(`sinir gecisi = ${kayit.length} (${kayit.join(" -> ")})`);
console.log(`dokunulan birim = ${birim.size}, serilestirme noktasi = 0, sinirdan gecen bayt = 0`);

const ITHAL = /from\s+"(\.[^"]+)"/g;
function kapanis(giris) {
  const yigit = [giris], gorulen = new Set();
  while (yigit.length > 0) {
    const d = normalize(yigit.pop());
    if (gorulen.has(d)) continue;
    gorulen.add(d);
    for (const [, y] of readFileSync(d, "utf8").matchAll(ITHAL)) yigit.push(join(dirname(d), y));
  }
  return [...gorulen].sort();
}

const kume = kapanis("tek-parca/uygulama.mjs");
console.log(`dagitim birimi = 1, birimin kapanisi = ${kume.length} dosya (${kume.join(", ")})`);
console.log(`ucret.mjs degisirse: degisen dosya = 1, yeniden yayinlanan dosya = ${kume.length}`);
for (const g of ["ortak/ucret.mjs", "ortak/operasyon.mjs"]) {
  console.log(`${g} tek basina kosmak icin gereken komsu = ${kapanis(g).length - 1}`);
}
```

```sh
node tek-parca/olc.mjs
```

```
teklif ciktisi = {"id":"G1","net":5100,"gun":3,"tasiyici":"MT"}
sinir gecisi = 4 (uygulama.teklif -> ucret.net -> operasyon.teslimGunu -> operasyon.tasiyici)
dokunulan birim = 3, serilestirme noktasi = 0, sinirdan gecen bayt = 0
dagitim birimi = 1, birimin kapanisi = 4 dosya (ortak/operasyon.mjs, ortak/sar.mjs, ortak/ucret.mjs, tek-parca/uygulama.mjs)
ucret.mjs degisirse: degisen dosya = 1, yeniden yayinlanan dosya = 4
ortak/ucret.mjs tek basina kosmak icin gereken komsu = 0
ortak/operasyon.mjs tek basina kosmak icin gereken komsu = 0
```

## Sayıların Okunması

Dört sınır geçişi var ve dördü de fonksiyon çağrısıdır. Serileştirme noktası 0, sınırdan geçen
bayt 0: `g` nesnesi ücretlendirmeye kopyalanmadan, aynı bellekteki başvurusuyla geçti. Bu
biçemin en somut kazancıdır. Sınırdan geçen veri için bir biçim kararlaştırılmaz, sürüm
uyumluluğu tartışılmaz, dönüştürme noktası tanımlanmaz — çünkü dönüştürme yoktur.

İkinci sayı çifti biçemin sınırını gösterir. Ücretlendirme kuralında bir satır değişirse
değişen dosya 1'dir, ama yeniden yayınlanan dosya 4'tür. Ücretlendirmenin asgari ücretini
düzelten bir sürüm, operasyon bağlamının kodunu da yeniden yayına sokar. Bu, kod düzeyinde bir
bağlaşım değildir; iki bağlam birbirini ithal etmiyor. Yayın düzeyinde bir bağlaşımdır ve
kaynağı biçemin kendisidir.

Son iki satır önemli bir ayrımı ortaya koyar. Her iki bağlam **tek başına sınanabilir**: hiçbiri
ötekinin dosyasına ihtiyaç duymuyor, gereken komşu sayısı 0. Yani tek parça mimari bağımsız
*sınanabilirliği* engellemez; engellediği bağımsız *yayındır*. Bu iki şeyin karıştırılması,
biçem tartışmalarında en sık yapılan hatadır.

## Paylaşılan Kader

Tek parça biçemin ikinci sınırı arıza davranışındadır. İki bağlam aynı süreçte koştuğu için
süreci sonlandıran bir kusur ikisini birden durdurur. İstek başına yakalama koymak yetmez:
yakalama yalnız kendi çağrı yığıtındaki hatayı tutar, sonraya bırakılmış bir görevden yükselen
hatayı tutmaz.

```js
// tek-parca/ariza.mjs — istek basina yakalama varken bile sureci sonlandiran kusur
import * as ucret from "../ortak/ucret.mjs";
import * as operasyon from "../ortak/operasyon.mjs";

const ISTEK = [
  { birim: "ucret", id: "G1" }, { birim: "operasyon", id: "G2" },
  { birim: "ucret", id: "G3", kusurlu: true }, { birim: "operasyon", id: "G4" },
  { birim: "ucret", id: "G5" }, { birim: "operasyon", id: "G6" },
];

let yanitlanan = 0;
process.on("exit", () => {
  console.log(`yanitlanan istek = ${yanitlanan} / ${ISTEK.length}`);
  console.log(`ayakta kalan birim = ${yanitlanan === ISTEK.length ? 2 : 0} / 2`);
});

for (const istek of ISTEK) {
  try {
    if (istek.birim === "ucret") {
      if (istek.kusurlu) setTimeout(() => { throw new RangeError(`tarife kademesi yok: ${istek.id}`); });
      console.log(`${istek.id} ucret  = ${ucret.net(4, "35", 0.15)}`);
    } else {
      console.log(`${istek.id} rota   = ${operasyon.rota("35").join("-")}`);
    }
    yanitlanan += 1;
  } catch (e) {
    console.log(`${istek.id} yakalandi: ${e.message}`);
  }
  await new Promise((c) => setTimeout(c, 5));
}
```

Yığıt izi standart hata akışına yazılır; aşağıdaki komut onu ayırıp yalnız sayılan çıktıyı ve
çıkış kodunu bırakır.

```sh
node tek-parca/ariza.mjs 2>/dev/null; echo "cikis kodu = $?"
```

```
G1 ucret  = 5100
G2 rota   = 34-41-35
G3 ucret  = 5100
yanitlanan istek = 3 / 6
ayakta kalan birim = 0 / 2
cikis kodu = 1
```

Altı isteğin üçü yanıtlandı. Kusur ücretlendirme bağlamındaydı, ama G4 ve G6 operasyon
isteklerinin ikisi de yanıtsız kaldı; ayakta kalan birim 0. Arıza yalıtımı bu biçemde ölçülemez
bir nitelik değildir, ölçülür ve sonucu sıfırdır.

## Biçemin Bıraktığı Fatura

Sayılar bir kalite niteliği ödünleşimidir ve iki yönü de aynı derste görünüyor. Kazanç
tarafında: sınırdan geçen bayt 0, serileştirme noktası 0, bir isteğin uçtan uca izlenmesi için
bakılacak süreç sayısı 1. Kayıp tarafında: bir dosyalık değişiklik için yeniden yayınlanan dosya
4, altı istekte ayakta kalan birim 0.

Bu ödünleşimin yönü ekip ve sürüm sıklığıyla değişir. İki bağlamı aynı ekip aynı takvimde
yayınlıyorsa "yeniden yayınlanan dosya 4" bir maliyet değildir; yayın zaten birlikte
yapılacaktı. Bağlamlar ayrı takvimlere geçtiğinde aynı sayı doğrudan bir bekleme süresine
dönüşür: ücretlendirme sürümü, operasyon tarafının kararlı olmasını beklemek zorundadır.

Ölçek sınırı da aynı yerden çıkar. Süreç tek olduğu için kopyalama ancak bütün olarak yapılır:
ücretlendirme isteklerinin sayısı arttığında operasyon kodu da onunla birlikte çoğaltılır.
Kopyalanan birim sayısı 1 olduğu sürece hangi bağlamın yüklendiği bilgisi kopyalama kararına
giremez.

## Özet

- Dağıtım birimi birlikte yayınlanmak zorunda olan dosya kümesidir; tek parça mimari bütün
  bağlamları tek dağıtım biriminde tutan biçemdir.
- Teklif isteği 3 birime dokundu ve 4 sınırdan geçti; dördü de fonksiyon çağrısı olduğu için
  serileştirme noktası 0, sınırdan geçen bayt 0 ölçüldü.
- Bir dosyada yapılan değişiklik 4 dosyayı yeniden yayınlattı; bu, kod bağlaşımı değil yayın
  bağlaşımıdır ve kaynağı biçemin kendisidir.
- Her iki bağlam tek başına koşabildi (gereken komşu 0); biçem bağımsız sınanabilirliği değil
  bağımsız yayını engelliyor.
- Süreci sonlandıran bir kusurda altı isteğin 3'ü yanıtlandı ve ayakta kalan birim 0 oldu; arıza
  yalıtımı ölçüldü ve sıfır çıktı.
- Ödünleşimin yönü sabit değildir: bağlamlar aynı takvimde yayınlanıyorsa yayın bağlaşımı bedel
  değildir, ayrı takvimlere geçildiğinde bekleme süresine dönüşür.

## Sonraki Adım

Yayın bağlaşımının bedeli iki bağlam ayrı takvimlere geçtiğinde ortaya çıkıyor. İlk çözüm
denemesi bağlamları ayırmak değil, aralarına paylaşılan bir tümleştirme yüzeyi koymaktır: her
bağlam kendi dağıtım birimine çıkar, ama ikisi de ortak bir kayıt biçimi ve ortak bir çağrı
yolu üzerinden konuşur. Bu düzen kurum çapında yeniden kullanımı hedefler ve ölçüsü de oradan
gelir: ortak biçimin alan sayısı, her sınır geçişindeki dönüştürme noktası sayısı ve ortak
biçimde bir alan değiştiğinde birlikte yayınlanmak zorunda kalan servis sayısı. Sonraki ders bu
üç sayıyı ölçer.
