---
title: 'Uyumlu Arayüz Katmanları'
source: 'https://academia.sh/tr/kurslar/model-apileri/uyumlu-api-katmanlari'
course: "Model API'leri ile Uygulama Geliştirme"
language: tr
updated: '2026-08-17T18:06:37+00:00'
license: 'CC BY-SA 4.0'
---

# Uyumlu Arayüz Katmanları

İki kurgu sağlayıcının ve aralarındaki ortak arayüzün alan alan sayılması: sağlayıcı A on iki alan sunuyor, sekizi taşınıyor ve dördü kayboluyor; sağlayıcı B on alan sunuyor, sekizi taşınıyor ve ikisi kayboluyor. Durdurma dizisi alanı yalnız A'da olduğu için kesişimde yer bulamıyor ve çıkış belirteci 773'ten 1638'e çıkıyor. Yüz yirmi çağrının 117'si uzunluk sınırında kesiliyor; iki sağlayıcı da bunu kendi arayüzünde bildiriyor, ortak arayüzden okunabilen kesilme sayısı 0. Aynı ortak çağrıda sıcaklık 0,6 A'da 0,5500, B'de 0,5000 isabet veriyor; sıcaklık 0,4 ile 0,6 B'de aynı ayara yuvarlandığı için ikisi de 0,5000 verirken A 0,7583 ile 0,5500 arasında ayrışıyor.

Önceki dersteki gömme uç noktası ile daha önceki derslerdeki metin uç noktası aynı sağlayıcıdan
gelmek zorunda değil. Bir uygulama büyüdükçe ikinci bir sağlayıcı eklenir, bir görev ucuz olana
taşınır, bir başkası elde tutulur. O noktada her çağrı yerinde ayrı ayrı yazılmış alan adlarıyla
uğraşmak istenmez ve **ortak bir arayüz** yazılır: tek bir işlev, tek bir ad kümesi, altında
sağlayıcıya göre değişen bir eşleme.

Bu ders o katmanın ne yaptığını sayar. İki sağlayıcı **benzetici düzeyinde** kurulur, ikisi de
kurgudur ve ikisi de altta aynı motoru çağırır. Ölçülen şey **soyutlamanın taşıdığı ve kaybettiği
alanlardır**: kaç alan geçiyor, kaç alan düşüyor ve düşen alanların hangisi bir ölçüyü görünmez
kılıyor. Veri Analitiği müfredatının Python ile Veri Analizi kursunda kurulan kural burada aynen
geçerlidir: **bir soyutlama altındaki kararı gizler.**

- **AK57.** Kod bir **benzeticidir**. **İki sağlayıcı da kurgudur** ve benzetici düzeyinde
  kurulur; gerçek bir uç nokta çağrılmaz. Tohum **20260218**, ikinci koşum **20260219**.
- **AK58.** İki sağlayıcı **tek bir motoru** paylaşır. Böylece aralarındaki bütün farklar
  **arayüz farkıdır**, model farkı değil.
- **AK59.** Sağlayıcı A **on iki alan**, sağlayıcı B **on alan** sunar; adlar blokta listelidir.
  B'de **durdurma dizisi alanı yoktur** ve B'nin `cesit` ayarı sıfır ile dört arasında **tam
  sayıdır**, yani kendi ölçeğine oturur.
- **AK60.** Ortak arayüz iki sağlayıcının **kesişimidir**: yalnız her ikisinde de karşılığı olan
  alan taşınabilir. Bir alan tek sağlayıcıda varsa ortak arayüzde yeri yoktur.
- **AK61. Durdurma dizisi** üretimi belirli bir belirteçte kesen alandır; bu derste üç yanıt
  kalıbının da içindeki ortak bir sözcükte devreye girer.
- **AK62.** Benzetici her çağrının **gerçek bitiş nedenini** kendi kaydına yazar; ortak arayüzü
  kullanan bir uygulamanın böyle bir kaydı olmaz.

## İki Sağlayıcı ve Aradaki Kesişim

Aşağıdaki blok motoru, iki sağlayıcıyı, alan envanterini ve ortak arayüzü kurar. Envanter bir
düzyazı iddiası değil, kod içinde tutulan bir listedir; taşınan ve kaybedilen alanlar küme
işlemiyle sayılır.

```python
# BENZETICI -- KURGUDUR. Iki saglayici da kurgudur ve benzetici duzeyinde
# kurulur. Gercek bir model uc noktasi cagrilmaz.
import math
TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE = 240


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):                      # KURGU belirtecleyici, parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = [("bu ayki fatura tutari gecen aya gore cok yuksek geldi", "fatura"),
         ("faturami odedim ama sistemde borc gorunuyor", "fatura"),
         ("fatura ayrintisini nereden gorebilirim", "fatura"),
         ("evde su akmiyor bir ariza var galiba", "ariza"),
         ("baglanti bozuk oldu ve hic calismiyor", "ariza"),
         ("ariza kaydi actim ama ekip gelmedi", "ariza"),
         ("sayac okumasi yanlis girilmis endeks tutmuyor", "sayac"),
         ("sayac degisimi icin randevu istiyorum", "sayac"),
         ("sayac uzerindeki endeks ile fatura ayni degil", "sayac"),
         ("hangi tarife basamagindayim ogrenmek istiyorum", "tarife"),
         ("tarife degisikligi icin ne yapmam gerekiyor", "tarife"),
         ("birim ucret abone tipine gore degisiyor mu", "tarife"),
         ("mahallede kesinti var ne zaman gelecek", "kesinti"),
         ("planli kesinti duyurusu nereden takip edilir", "kesinti"),
         ("aksamdan beri kesinti yasiyoruz", "kesinti")]
TALEP = []
for i in range(120):                    # 120 KURGU destek talebi
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    TALEP.append({"no": 4001 + i, "konu": k,
                  "metin": [x for x in KALIP if x[1] == k][int(r() * 3)][0]})
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti"}
KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
SERBEST = [                             # ucuncu kalip hicbir etiket tasimaz
    "talebiniz {} konusunda kaydedildi ayrica ekibimiz sizinle iletisime gececek"
    " ve sonuc size bildirilecektir",
    "{} kaydiniz acilmistir ayrica islem numaraniz kisa mesajla tarafiniza"
    " gonderilecek ve surec takip edilebilecektir",
    "kaydiniz alinmistir ayrica ilgili birim inceleyip size donus yapacak"
    " ve gerekirse ek belge istenecektir"]
SAYAC, GERCEK = [0], []          # GERCEK: benzeticinin kendi kaydi


def motor(istem, en_uzun, sicaklik, dur, tohum):
    """Iki saglayicinin da altinda calisan tek KURGU motor."""
    SAYAC[0] += 1
    bel = belirtecle(istem)
    bos = {"metin": "", "hal": "hata", "giris": len(bel), "cikis": 0}
    if len(bel) > PENCERE or SAYAC[0] % 37 == 0:
        n = "baglam_asimi" if len(bel) > PENCERE else "hiz_siniri"
        GERCEK.append(n)
        return dict(bos, bitis=n)
    r = uretec(tohum ^ izno(istem))
    aday = [k for k in KAVRAM if k[:5] in bel]
    if len(aday) < 3:
        aday = list(KAVRAM)
    p = {k: 0.15 for k in aday}
    for t in bel:
        if IZ.get(t) in p:
            p[IZ[t]] += 1.0
    if sicaklik <= 0.0:
        secim = max(sorted(p), key=lambda a: p[a])
    else:
        ad = sorted(p)
        w = [math.exp(p[a] / sicaklik) for a in ad]
        secim = ad[ayrik(r(), [q / sum(w) for q in w])]
    kalip = SERBEST[ayrik(r(), [0.40, 0.36, 0.24])]
    cb, bitis = belirtecle(kalip.format(secim)), "dogal"
    for i, t in enumerate(cb):
        if t in dur:                    # durdurma dizisi: uretim burada kesilir
            cb, bitis = cb[:i], "durdurma"
            break
    if len(cb) > en_uzun:
        cb, bitis = cb[:en_uzun], "uzunluk"
    GERCEK.append(bitis)
    tam = kalip.format(secim)
    return {"metin": tam if bitis == "dogal" else " ".join(cb), "hal": "tamam",
            "giris": len(bel), "cikis": len(cb), "bitis": bitis}


def saglayici_a(istem, en_cok=14, dagilim=0.6, dur=(), kip="serbest", tohum=TOHUM):
    """KURGU saglayici A. Alan adlari ve yanit bicimi kendisine ozgudur."""
    s = motor(istem, en_cok, dagilim, dur, tohum)
    return {"metin": s["metin"], "hal": s["hal"], "giris_bel": s["giris"],
            "cikis_bel": s["cikis"], "bitis": s["bitis"],
            "kesildi": s["bitis"] == "uzunluk"}


def saglayici_b(mesaj, sinir=14, cesit=2, sema=None, anahtar=TOHUM):
    """KURGU saglayici B. cesit 0-4 arasi tam sayidir ve kendi olcegine oturur."""
    s = motor(mesaj, sinir, cesit / 4 * 1.6, (), anahtar)
    return {"cikti": s["metin"], "durum": s["hal"], "neden": s["bitis"],
            "kullanim": {"g": s["giris"], "c": s["cikis"]}}


ALAN = {"A": ["istem", "en_cok", "dagilim", "dur", "kip", "tohum",
              "metin", "hal", "giris_bel", "cikis_bel", "bitis", "kesildi"],
        "B": ["mesaj", "sinir", "cesit", "sema", "anahtar",
              "cikti", "durum", "kullanim.g", "kullanim.c", "neden"]}
ESLEME = {"istem": ("istem", "mesaj"), "en_uzun": ("en_cok", "sinir"),
          "sicaklik": ("dagilim", "cesit"), "tohum": ("tohum", "anahtar"),
          "yanit": ("metin", "cikti"), "durum": ("hal", "durum"),
          "giris": ("giris_bel", "kullanim.g"), "cikis": ("cikis_bel", "kullanim.c")}


def ortak(saglayici, istem, en_uzun=14, sicaklik=0.6, tohum=TOHUM):
    """Ortak arayuz: yalnizca ESLEME'deki sekiz alan tasinir."""
    if saglayici == "A":
        y = saglayici_a(istem, en_cok=en_uzun, dagilim=sicaklik, tohum=tohum)
        return {"yanit": y["metin"], "durum": y["hal"],
                "giris": y["giris_bel"], "cikis": y["cikis_bel"]}
    y = saglayici_b(istem, sinir=en_uzun, cesit=round(sicaklik * 4), anahtar=tohum)
    return {"yanit": y["cikti"], "durum": y["durum"],
            "giris": y["kullanim"]["g"], "cikis": y["kullanim"]["c"]}


ONEK5 = {k[:5]: k for k in KONU}        # kesilen yanitta etiket parcalanmis olabilir


def oku(y):
    return next((ONEK5[s[:5]] for s in y.split() if s[:5] in ONEK5), None)


YONERGE = ("Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife ,"
           " kesinti . Talep: ")


print("ortak arayuzun alanlari :", " , ".join(ESLEME))
for i, ad in enumerate(ALAN):
    tasinan = [e[i] for e in ESLEME.values()]
    kayip = [a for a in ALAN[ad] if a not in tasinan]
    print(f"saglayici {ad}: {len(ALAN[ad])} alan , tasinan {len(tasinan)} ,"
          f" kaybedilen {len(kayip)} -> {' , '.join(kayip)}")
istem = YONERGE + TALEP[2]["metin"]
print("\nayni istem , dort yol -- metin disindaki alanlar:")
for ad, y in (("A kendi + dur", saglayici_a(istem, dur=("ayric",))),
              ("B kendi", saglayici_b(istem)),
              ("ortak -> A", ortak("A", istem)),
              ("ortak -> B", ortak("B", istem))):
    alan = " , ".join(f"{k}={v}" for k, v in y.items()
                      if k not in ("metin", "cikti", "yanit"))
    print(f" {ad:<14} {alan}")
```

```
ortak arayuzun alanlari : istem , en_uzun , sicaklik , tohum , yanit , durum , giris , cikis
saglayici A: 12 alan , tasinan 8 , kaybedilen 4 -> dur , kip , bitis , kesildi
saglayici B: 10 alan , tasinan 8 , kaybedilen 2 -> sema , neden

ayni istem , dort yol -- metin disindaki alanlar:
 A kendi + dur  hal=tamam , giris_bel=33 , cikis_bel=5 , bitis=durdurma , kesildi=False
 B kendi        durum=tamam , neden=uzunluk , kullanim={'g': 33, 'c': 14}
 ortak -> A     durum=tamam , giris=33 , cikis=14
 ortak -> B     durum=tamam , giris=33 , cikis=14
```

Envanter satırları soyutlamanın aritmetiğini veriyor. Sağlayıcı A on iki alan sunuyor, sekizi
taşınıyor, dördü kayboluyor. Sağlayıcı B on alan sunuyor, sekizi taşınıyor, ikisi kayboluyor.
Kaybın sebebi ortak arayüzün kötü tasarlanmış olması değil: `dur` ve `kip` yalnız A'da,
`sema` yalnız B'de var. **Kesişim ancak iki tarafta da karşılığı olanı taşıyabilir**, ve bir
sağlayıcı ne kadar çok alan sunarsa ortak arayüzde o kadar çok alanını kaybeder.

Dört yanıt biçimi aynı istemde yan yana duruyor. A kendi arayüzüyle çağrıldığında durdurma dizisi
işini yapıyor: çıkış beş belirteç ve `bitis` alanı `durdurma` diyor. B kendi arayüzüyle
çağrıldığında çıkış on dört belirteç ve `neden` alanı `uzunluk` diyor, yani yanıt kesildi. Ortak
arayüzden bakan iki satır ise ayırt edilemez: ikisi de `durum: tamam` ve `cikis: 14`. Yanıtın
tamamlanıp tamamlanmadığı **bu iki satırda yazmıyor**.

## Kaybolan Alanların Bedeli

Yüz yirmi kurgu talep beş yoldan geçirilir. İlk ikisi A'nın kendi arayüzü (durdurma dizisiz ve
dizili), üçüncüsü B'nin kendi arayüzü, son ikisi ortak arayüz. Her satırda giriş ve çıkış
belirteci, etiket isabeti, ikinci koşum isabeti, benzeticinin kaydettiği **gerçek** kesilme sayısı
ve o yoldan **okunabilen** kesilme sayısı basılır.

```python
YOL = ("A kendi", "A kendi + dur", "B kendi", "ortak -> A", "ortak -> B")


def kosum(yol, sicaklik=0.6, tohum=TOHUM):
    SAYAC[0], GERCEK[:] = 0, []
    g = c = dg = gor = 0
    for x in TALEP:
        istem = YONERGE + x["metin"]
        if yol.startswith("A kendi"):
            y = saglayici_a(istem, dagilim=sicaklik, tohum=tohum,
                            dur=("ayric",) if "dur" in yol else ())
            m, gi, ci = y["metin"], y["giris_bel"], y["cikis_bel"]
            gor += y["kesildi"]                     # bitis alani okunabiliyor
        elif yol == "B kendi":
            y = saglayici_b(istem, cesit=2, anahtar=tohum)
            m, gi, ci = y["cikti"], y["kullanim"]["g"], y["kullanim"]["c"]
            gor += y["neden"] == "uzunluk"          # neden alani okunabiliyor
        else:
            y = ortak(yol[-1], istem, sicaklik=sicaklik, tohum=tohum)
            m, gi, ci = y["yanit"], y["giris"], y["cikis"]   # bitis nedeni yok
        g, c = g + gi, c + ci
        dg += oku(m) == x["konu"]
    return g, c, dg / 120, GERCEK.count("uzunluk"), gor


print("yol             giris  cikis  isabet  ikinci kosum  gercek kesilme  okunan")
for yol in YOL:
    a, b = kosum(yol), kosum(yol, tohum=TOHUM + 1)
    print(f"{yol:<14} {a[0]:>6} {a[1]:>6} {a[2]:>7.4f} {b[2]:>13.4f}"
          f" {a[3]:>15} {a[4]:>7}")
print("\nayni ortak cagri , iki saglayici:")
print("sicaklik  B'ye giden cesit  ortak -> A  ortak -> B  fark")
for s in (0.0, 0.2, 0.4, 0.6, 0.8, 1.0):
    a, b = kosum("ortak -> A", s)[2], kosum("ortak -> B", s)[2]
    print(f"{s:>8.1f} {round(s * 4):>17} {a:>11.4f} {b:>11.4f} {b - a:>+6.4f}")
```

```
yol             giris  cikis  isabet  ikinci kosum  gercek kesilme  okunan
A kendi          4054   1638  0.5500        0.5000             117     117
A kendi + dur    4054    773  0.5500        0.5000               0       0
B kendi          4054   1638  0.5000        0.3917             117     117
ortak -> A       4054   1638  0.5500        0.5000             117       0
ortak -> B       4054   1638  0.5000        0.3917             117       0

ayni ortak cagri , iki saglayici:
sicaklik  B'ye giden cesit  ortak -> A  ortak -> B  fark
     0.0                 0      0.8417      0.8417 +0.0000
     0.2                 1      0.7583      0.7583 +0.0000
     0.4                 2      0.7583      0.5000 -0.2583
     0.6                 2      0.5500      0.5000 -0.0500
     0.8                 3      0.5000      0.3167 -0.1833
     1.0                 4      0.4500      0.3167 -0.1333
```

İkinci satır kaybolan `dur` alanının bedelidir. Durdurma dizisi kullanıldığında çıkış belirteci
**773**, kullanılmadığında **1638**: iki katından fazla. İsabet iki satırda da 0,5500, yani bu
belirteçlerin hiçbiri işe yaramıyor; kalıbın gövdesinden sonra gelen kibar kapanış cümlesi
ödeniyor ve atılıyor. Ortak arayüz bu alanı **sunamaz**, çünkü B'de karşılığı yoktur. Kesişimin
bedeli burada doğrudan belirteçle yazılıdır.

Son iki sütun kaybolan `bitis` ve `neden` alanlarının bedelidir ve bu dersin en sert satırıdır.
Yüz yirmi çağrının **117'si** uzunluk sınırında kesiliyor. A kendi arayüzünde bunu `kesildi`
alanıyla, B kendi arayüzünde `neden` alanıyla bildiriyor: iki sağlayıcı da dürüst. Ortak arayüzden
okunabilen kesilme sayısı ise **0**. Kesilme ortadan kalkmadı, **sayılamaz hâle geldi**. Kursun
kuralı tam buraya oturuyor: başarısızlığı yazılmayan çağrı ölçülmemiş sayılır. Ortak arayüzü
kullanan bir uygulama yüz on yedi yarım yanıtı kayıt sistemine yazar ve hiçbir sayacı kıpırdamaz.

Kaybolan alanın yerine konabilecek tek şey bir çıkarımdır: `cikis` sınıra eşitse yanıt kesilmiş
sayılır. Bu çıkarım sınıra tam denk gelerek doğal biten yanıtları da kesilmiş sayar, yani bir
ölçüm alanının yerine yeni bir hata sınıfı geçer.

## Aynı Düğme, İki Ayrı Anlam

Alan sayısı soyutlamanın yalnız bir yüzüdür. Taşınan sekiz alanın **aynı şeyi ifade ettiği**
varsayımı ikinci ve daha sinsi yüzüdür. Ortak arayüzün `sicaklik` alanı A'ya olduğu gibi gider;
B'ye giderken sıfır ile dört arasında bir tam sayıya yuvarlanır, çünkü B'nin ölçeği odur.

Alt tablo bunun iki ayrı sonucunu gösteriyor. Birincisi: aynı ayar iki ayrı davranış demek.
Sıcaklık 0,4'te A 0,7583, B 0,5000 veriyor; fark **0,2583**. Aynı satırdaki iki sayı aynı işlevin
aynı argümanıyla üretildi. İkincisi: iki ayrı ayar aynı davranış demek. Sıcaklık 0,4 ile 0,6 B'de
aynı `cesit` değerine yuvarlanıyor ve ikisi de **0,5000** veriyor, oysa A'da 0,7583 ile 0,5500
arasında **0,2083**'lük bir ayrım var. Ortak arayüzün sürekli görünen düğmesi B üzerinde beş
konumludur ve aradaki konumlar sessizce yutulur.

Bu okumaların hangisinin ölçülmüş sayıldığı ikinci koşum sütunundan çıkar. A'nın iki koşum farkı
0,0500, B'nin 0,1083. Sıcaklık 0,6 satırındaki 0,0500'lük sağlayıcı farkı koşum farkının tam
kendisidir ve **ölçülmemiş sayılır**; o değerde iki sağlayıcı arasında bir seçim yapılamaz.
Sıcaklık 0,4 satırındaki 0,2583 ise koşum farkının beş katıdır ve gerçektir. Ortak arayüzü
kullanan bir uygulama sağlayıcı değiştirdiğinde bu farkı hiçbir yerde görmez: alan adları aynı
kalır, çağrı aynı kalır, yalnız sayı değişir.

## Özet

- Ortak arayüz iki sağlayıcının kesişimidir: A'nın on iki alanından sekizi taşınır ve dördü
  düşer, B'nin on alanından sekizi taşınır ve ikisi düşer.
- Yalnız bir sağlayıcıda bulunan alan kesişime giremez; `dur` ve `kip` A'da, `sema` B'de kalır.
- Durdurma dizisinin kaybı belirteçle ödenir: çıkış 773'ten 1638'e çıkar, isabet 0,5500'de sabit
  kalır, yani eklenen belirteçler işe yaramaz.
- Yüz yirmi çağrının 117'si uzunluk sınırında kesilir; iki sağlayıcı da bunu kendi alanında
  bildirir, ortak arayüzden okunabilen kesilme sayısı 0'dır.
- Taşınan bir alan da aynı anlama gelmeyebilir: sıcaklık 0,4'te iki sağlayıcı 0,2583 ayrışır,
  0,4 ile 0,6 ise B'de aynı ayara yuvarlandığı için tek bir değere çöker.
- Sağlayıcı farkının ölçülmüş sayılması koşum farkını aşmasına bağlıdır: 0,6 satırındaki 0,0500
  koşum farkının kendisidir, 0,4 satırındaki 0,2583 onun beş katıdır.

## Sonraki Adım

Bu derse kadar her ölçü **istek başına bir çağrı** varsayımıyla yazıldı: yüz yirmi talep, yüz
yirmi çağrı. Oysa yönerge her çağrıda yeniden gönderiliyor ve tabloda giriş belirtecinin 4054'te
sabit kalmasının sebebi budur. Talepler bir kerede biriktirilip tek çağrıda gönderilseydi bu
tekrar ödenmezdi. Sonraki ders toplu çağrıyı ölçer ve tek bir soruya bağlar: toplu boyut
büyüdükçe çağrı sayısı ve belirteç düşerken, **tek bir başarısızlığın etkilediği istek sayısı**
ne oluyor.
