---
title: 'Sınıf Diyagramları'
source: 'https://academia.sh/tr/kurslar/modelleme-ve-gosterim/sinif-diyagramlari'
course: 'Modelleme ve Gösterim'
language: tr
updated: '2026-08-17T18:08:16+00:00'
license: 'CC BY-SA 4.0'
---

# Sınıf Diyagramları

İlişki türü ve çokluk simgelerinin belirsizlikten aldığı pay: 20 simge 2048, 25 simge 64, 31 simge 1 sistem bırakıyor; ikili bir alanın simgesi tam bir bit alırken üç değerli bir alanınki 1,58 bit alıyor.

Önceki ders tek bir sayı bıraktı: yirmi simgelik yapı gösterimi 2048 sistemi tek diyagrama
düşürüyor. Sayı tek başına az şey söylüyor. Diyagrama simge eklemek onu düşürür, ama ne kadar
düşürdüğü ölçülmedi — bir simge belirsizliği yarıya mı indiriyor, daha çoğunu mu alıyor, hiç
almayanı var mı.

Sınıf gösterimi bu soruyu yanıtlamak için elverişli, çünkü ilişki simgelerinin her biri belirli
bir olguyu yazıyor ve yazılmadığında o olgu düşüyor. Sınıfın, kalıtımın ve arayüzün ne olduğu
Programlama Temelleri kursunda kuruldu; bu ders onları tanımlamıyor. Ölçtüğü tek şey şu:
**ilişki türü** ve **çokluk** simgeleri, aynı gösterime düşen sistem sayısını kaç kat
düşürüyor.

## Simge Başına Bir Bit

Ortak tanım üç ayrıntı düzeyi tanımlıyor. Sıfırıncı düzeyde her bağın yalnız kaynağı, hedefi,
yönü ve çokluğu yazılıyor. Birinci düzeyde **yaşam** alanı da yazılıyor: bağın bir yaşam
döngüsü sahipliği taşıyıp taşımadığı. İkinci düzeyde topluluk taşıyan bağların **sıralı** ve
**benzersiz** alanları da köşeli notlar olarak ekleniyor.

- **YD8** — Üç düzey aynı sistem üzerinde ölçülür; değişen tek şey yazılan alan kümesidir.
- **YD9** — Belirsizliğin bit karşılığı, aynı gösterime düşen sistem sayısının ikili
  logaritmasıdır. Tek sistem kalırsa bit sıfırdır ve gösterim geri çevrilebilir olmuştur.

```python
"""M01/K06 ortak tanim (kesit): yapi gosterimi uc ayrinti duzeyinde ve her duzeyin
ayni gosterime dusurdugu sistem sayisi. Sayim tam sayimdir."""
from itertools import product
from math import log2

BAGLAR = [
    {"ad": "b1", "kaynak": "IsEmri", "hedef": "Usta",  "yon": "tek", "cokluk": "N:1",
     "yasam": "bagimsiz", "sirali": False, "benzersiz": True},
    {"ad": "b2", "kaynak": "IsEmri", "hedef": "Kalem", "yon": "tek", "cokluk": "1:N",
     "yasam": "bagimli",  "sirali": True,  "benzersiz": False},
    {"ad": "b3", "kaynak": "Kalem",  "hedef": "Parca", "yon": "tek", "cokluk": "N:1",
     "yasam": "bagimsiz", "sirali": False, "benzersiz": True},
    {"ad": "b4", "kaynak": "Usta",   "hedef": "Tezgah", "yon": "cift", "cokluk": "N:M",
     "yasam": "bagimsiz", "sirali": False, "benzersiz": True},
    {"ad": "b5", "kaynak": "IsEmri", "hedef": "Belge", "yon": "tek", "cokluk": "1:N",
     "yasam": "bagimli",  "sirali": True,  "benzersiz": True},
]


def gizli_alanlar(bag):
    alanlar = ["yasam"]
    if bag["cokluk"] in ("1:N", "N:M"):
        alanlar += ["sirali", "benzersiz"]
    return alanlar


def yapi_gosterimi(baglar, ayrinti=0):
    simge = []
    for b in baglar:
        s = {"kaynak": b["kaynak"], "hedef": b["hedef"], "yon": b["yon"], "cokluk": b["cokluk"]}
        if ayrinti >= 1:
            s["yasam"] = b["yasam"]
        if ayrinti >= 2:
            for a in gizli_alanlar(b):
                s[a] = b[a]
        simge.append(s)
    return simge


def simge_sayisi(gosterim):
    return sum(len(s) for s in gosterim)


def ayni_gosterime_dusen(baglar, ayrinti=0):
    secenek = {"yasam": ("bagimsiz", "bagimli"), "sirali": (False, True),
               "benzersiz": (False, True)}
    hedef = yapi_gosterimi(baglar, ayrinti)
    uzaylar = []
    for b in baglar:
        alanlar = gizli_alanlar(b)
        uzaylar.append([dict(zip(alanlar, d)) for d in product(*[secenek[a] for a in alanlar])])
    sayi = 0
    for secim in product(*uzaylar):
        aday = [dict(b, **s) for b, s in zip(baglar, secim)]
        if yapi_gosterimi(aday, ayrinti) == hedef:
            sayi += 1
    return sayi


YAZILAN = {0: "kaynak/hedef/yon/cokluk", 1: "+ yasam", 2: "+ sirali , benzersiz"}
olcum = []
print("ayrinti  yazilan alan             simge  dusen sistem   bit")
for a in (0, 1, 2):
    g = yapi_gosterimi(BAGLAR, a)
    s, d = simge_sayisi(g), ayni_gosterime_dusen(BAGLAR, a)
    olcum.append((s, d))
    print(f"  {a:5d}  {YAZILAN[a]:23s}{s:6d}{d:14d}{log2(d):7.2f}")
print()
print("gecis            eklenen simge  alinan bit  simge basina bit")
for (s0, d0), (s1, d1) in zip(olcum, olcum[1:]):
    print(f"  {s0:2d} -> {s1:2d} simge{s1 - s0:12d}{log2(d0) - log2(d1):12.2f}"
          f"{(log2(d0) - log2(d1)) / (s1 - s0):18.2f}")
```

```
ayrinti  yazilan alan             simge  dusen sistem   bit
      0  kaynak/hedef/yon/cokluk    20          2048  11.00
      1  + yasam                    25            64   6.00
      2  + sirali , benzersiz       31             1   0.00

gecis            eklenen simge  alinan bit  simge basina bit
  20 -> 25 simge           5        5.00              1.00
  25 -> 31 simge           6        6.00              1.00
```

Üç sayı yan yana. **Sistem:** beş bağ, 31 olgu. **Gösterim:** 20, 25 ya da 31 simge.
**Bedel:** sırasıyla 2048, 64 ve 1 sistem.

Alt tablo dersin ana sonucunu veriyor: **eklenen her simge tam olarak bir bit alıyor.** Beş
yaşam simgesi beş bit, altı sıralılık ve benzersizlik notu altı bit götürüyor; ne daha az ne
daha çok. Son satırda belirsizlik sıfır bite iniyor, yani 31 simgelik gösterim geri
çevrilebilir hâle geliyor — o gösterimi üreten tek bir sistem var ve okuyucu seçim yapmak
zorunda kalmıyor.

Bu tam örtüşme bir rastlantı değil. Gizli alanların hepsi ikili: yaşam iki değer, sıralı iki
değer, benzersiz iki değer. Bir ikili alanı yazmak seçenek uzayını tam yarıya indirir ve yarıya
inen bir uzay tam bir bit kaybeder. Bir sonraki bölüm bu koşulun kalktığı durumu ölçecek.

Ölçünün kapsamı da burada sınırlanıyor. Model yalnız bağ satırlarını sayıyor; sınıf adları,
öznitelikler ve işlemler modelin dışında ve dolayısıyla 2048 sayısı **yalnız ilişki
belirsizliğidir**. Gerçek bir sınıf gösterimi bunlardan fazlasını taşır ve taşıdığı her yeni
alan kendi gizli alanlarını da getirir; buradaki sayı bir alt sınırdır, bir toplam değildir.

## Yaşam Döngüsü Sahipliği

Yaşam simgesinin aldığı bit, gösterimde iki ilişki türünü ayırıyor. **Sıkı bileşim
(composition)** bir yaşam döngüsü sahipliği bildirir: sahip nesne silindiğinde parça nesne de
silinir, çünkü parçanın sahibinden bağımsız bir varlığı yoktur. **Gevşek bileşim
(aggregation)** sahiplik iddia etmez; parça, bütün silindikten sonra da durur. Bileşim
kavramının kendisi Programlama Temelleri kursunda kuruldu; buradaki ek, iki türün ayrımının
**hangi olguyu** taşıdığıdır.

Ayrım, gösterimde tek simge; örnek düzeyinde ise silinen nesne sayısı.

- **YD10** — Örnek durum: bir iş emri, üç kalem, iki belge, bir usta, iki tezgâh, üç parça —
  toplam on iki nesne.
- **YD11** — Silme kökten başlar ve yalnız bağımlı bağlar üzerinden **geçişli** yayılır. Bir
  bağın hedefi silinmediyse ve kaynağı silindiyse, hedef **bağsız** kalır.
- **YD12** — Bir topluluğun geçerli içerik sayısı için dört parçalık bir katalog ve üç
  kalemlik bir iş emri alınır.

```python
"""Yazilmayan alanlarin ornek duzeyindeki karsiligi. Yasam alani silme yayilimini ,
sirali ve benzersiz alanlari bir toplulugun gecerli icerik sayisini belirler.
Ornek durum: 1 is emri , 3 kalem , 2 belge , 1 usta , 2 tezgah , 3 parca."""
from itertools import product

NESNE = {"IsEmri": 1, "Kalem": 3, "Parca": 3, "Usta": 1, "Tezgah": 2, "Belge": 2}
BAG = [("IsEmri", "Usta"), ("IsEmri", "Kalem"), ("Kalem", "Parca"),
       ("Usta", "Tezgah"), ("IsEmri", "Belge")]          # ortak tanimin b1..b5 sirasi
GERCEK = ("bagimsiz", "bagimli", "bagimsiz", "bagimsiz", "bagimli")


def silme(yasamlar, kok="IsEmri"):
    """Siki bilesim yasam dongusu sahipligidir: sahip silinince parca da silinir."""
    silinen, degisti = {kok}, True
    while degisti:
        degisti = False
        for (k, h), y in zip(BAG, yasamlar):
            if y == "bagimli" and k in silinen and h not in silinen:
                silinen.add(h)
                degisti = True
    bagsiz = {h for (k, h), y in zip(BAG, yasamlar)
              if y == "bagimsiz" and k in silinen and h not in silinen}
    return sum(NESNE[t] for t in silinen), sum(NESNE[t] for t in bagsiz), sorted(silinen)


dagilim = {}
for y in product(("bagimsiz", "bagimli"), repeat=5):
    n = silme(y)[0]
    dagilim[n] = dagilim.get(n, 0) + 1
print("toplam nesne:", sum(NESNE.values()), "| yasam secimi:", 2 ** 5,
      "| ayri silinen-nesne degeri:", len(dagilim))
print("  silinen nesne:", sorted(dagilim), "-> en az", min(dagilim), ", en cok", max(dagilim))
n, b, kume = silme(GERCEK)
print("yasam yazildiginda tek deger:", n, "nesne siliniyor", kume,
      "|", b, "nesne bagsiz kaliyor")
print()
print("b2 (IsEmri -> Kalem , 1:N): 4 parcali katalog , 3 kalemlik is emri")
print("  sirali  benzersiz  gecerli icerik sayisi")
for sirali in (False, True):
    for benzersiz in (False, True):
        icerik = set()
        for d in product(range(4), repeat=3):
            if benzersiz and len(set(d)) != len(d):
                continue
            icerik.add(d if sirali else tuple(sorted(d)))
        print(f"  {str(sirali):8s}{str(benzersiz):11s}{len(icerik):10d}")
```

```
toplam nesne: 12 | yasam secimi: 32 | ayri silinen-nesne degeri: 11
  silinen nesne: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] -> en az 1 , en cok 12
yasam yazildiginda tek deger: 6 nesne siliniyor ['Belge', 'IsEmri', 'Kalem'] | 4 nesne bagsiz kaliyor

b2 (IsEmri -> Kalem , 1:N): 4 parcali katalog , 3 kalemlik is emri
  sirali  benzersiz  gecerli icerik sayisi
  False   False              20
  False   True                4
  True    False              64
  True    True               24
```

Yirmi simgelik gösterime bakan biri, bir iş emri silindiğinde kaç nesnenin gideceğini
bilemiyor. Otuz iki yaşam seçimi **on bir ayrı** silinen-nesne değeri üretiyor ve aralık
1 ile 12 arasında: bütün bağlar bağımsızsa yalnız iş emri siliniyor, hepsi bağımlıysa
sistemdeki her nesne gidiyor. Diyagram bu on bir sonucun hepsiyle uyumlu.

Aralıkta bir boşluk var ve nedeni öğreticidir: on iki değerden yalnız **11 çıkmıyor**. Nesneler
tek tek değil kümeler hâlinde gidiyor — üç kalem birlikte, üç parça birlikte, iki belge
birlikte — ve bu kümelerin hiçbir birleşimi tam on bir nesne etmiyor. Silme davranışı sürekli
bir aralık değil, bağ yapısının izin verdiği ayrık bir değer kümesidir.

Yaşam simgeleri yazıldığında sonuç tek bir değere iniyor: **6 nesne** siliniyor — iş emri, üç
kalem, iki belge — ve **4 nesne bağsız kalıyor**: kalemlerin işaret ettiği üç parça ile atanmış
usta. Beş simgenin aldığı beş bit, örnek düzeyinde bir aralığı tek bir sayıya indiriyor. Bunun
karşılığı somuttur: silme yordamını yazan kişi, gösterimde o simge yoksa kararı kendisi verir
ve verdiği karar diyagramda yazmaz.

Bağsız kalan dört nesne ayrı bir kalemdir ve gevşek bileşimin bedelini gösterir. Parçalar
silinmiyor, ama artık onlara işaret eden bir kalem yok; sistemde ulaşılamaz durur. Sıkı bileşim
bu durumu ortadan kaldırır ve yerine başka bir şey koyar: sahibi silinen her nesne, başka bir
yerden kullanılıyor olsa bile gider.

Çokluk simgesi de aynı biçimde eksik. Gösterim `IsEmri` ile `Kalem` arasında 1:N yazıyor ve
bunun anlamı "bir iş emrinin birden çok kalemi var" cümlesiyle sınırlı. Dört parçalık bir
katalogda üç kalemlik bir iş emrinin kaç ayrı geçerli içeriği olduğu ise yazılmayan iki alana
bağlı: sıralı ve tekrar kabul eden bir listede **64**, sırasız ve benzersiz bir kümede **4**.
Aradaki on altı katlık aralık gösterimde tek bir `1:N` olarak duruyor.

## Simge Her Zaman Bir Bit Almaz

Simge başına tam bir bit sonucu, gizli alanların ikili olmasından geliyordu. Ortak tanımın
çözünürlük kuralı gereği bu koşul ikinci bir yapılandırmayla sınanır: yaşam alanı **üç** değer
alsaydı ne olurdu.

- **YD13** — Üç değerli yaşam alanı şunları ayırır: sahiplik iddia etmeyen düz **bağ
  (association)**, parçayı paylaşan **gevşek bileşim**, parçayı yaşam döngüsüyle birlikte
  taşıyan **sıkı bileşim**. Yazılan simge sayısı değişmez; yalnız simgenin ayırabildiği değer
  sayısı artar.

```python
"""Ikinci yapilandirma: yasam alani ikili degil uc degerli olsaydi. Uc deger: duz bag ,
gevsek bilesim , siki bilesim. Yazilan simge sayisi degismez ; degisen , bir simgenin
aldigi bit sayisidir. Sayim yine tam sayimdir."""
from itertools import product
from math import log2

COKLUKLAR = ["N:1", "1:N", "N:1", "N:M", "1:N"]          # ortak tanimin bes bagi


def gizli_alanlar(cokluk):
    return ["yasam", "sirali", "benzersiz"] if cokluk in ("1:N", "N:M") else ["yasam"]


def tam_sayim(yasam_degeri, yasam_yazili):
    uzaylar = []
    for c in COKLUKLAR:
        secenek = [range(1 if yasam_yazili else yasam_degeri) if a == "yasam" else range(2)
                   for a in gizli_alanlar(c)]
        uzaylar.append(list(product(*secenek)))
    return sum(1 for _ in product(*uzaylar))


print("yasam degeri  yasam yazili  simge  dusen sistem     bit")
for d in (2, 3):
    for yazili, simge in ((False, 20), (True, 25)):
        s = tam_sayim(d, yazili)
        print(f"{d:12d}  {str(yazili):12s}{simge:7d}{s:14d}{log2(s):8.2f}")
print()
for d in (2, 3):
    alinan = log2(tam_sayim(d, False)) - log2(tam_sayim(d, True))
    print(f"{d} degerli yasam alani: 5 simge {alinan:.2f} bit aliyor"
          f" , simge basina {alinan / 5:.2f}")
```

```
yasam degeri  yasam yazili  simge  dusen sistem     bit
           2  False            20          2048   11.00
           2  True             25            64    6.00
           3  False            20         15552   13.92
           3  True             25            64    6.00

2 degerli yasam alani: 5 simge 5.00 bit aliyor , simge basina 1.00
3 degerli yasam alani: 5 simge 7.92 bit aliyor , simge basina 1.58
```

Gösterim iki durumda da aynı: 20 simgeden 25 simgeye. Alınan bit ise 5,00'ten 7,92'ye çıkıyor,
simge başına 1,58. Kural şu biçimde düzeltiliyor: **bir simge, ayırdığı değer sayısının ikili
logaritması kadar bit alır.** İkili bir alanda bu tam bir bittir; üç değerli bir alanda 1,58,
dört değerli bir alanda iki bit olur.

Sonucun ters okuması daha kullanışlı. Yaşam simgesi yazılmadığında kaybedilen bilgi, o
simgenin **kaç şeyi ayırabildiğine** bağlıdır. Bağ ile gevşek bileşimi ayırmayan bir gösterimde
yazılmayan simge 1,00 bit götürür; ikisini ayıran bir gösterimde aynı yazılmayan simge 1,58
bit götürür. Gösterimi zenginleştirmek, o gösterimin **eksik bırakılmasını da pahalılaştırır**
— ve bu iki etki aynı tabloda görünmedikçe zenginleştirme bir kazanç sayılamaz.

## Özet

- Ayrıntısız yapı gösterimi 20 simge ve 2048 sistem; yaşam simgeleri eklenince 25 simge ve 64
  sistem; sıralılık ile benzersizlik notları da eklenince 31 simge ve tek sistem kalıyor.
- Bit cinsinden ölçüldüğünde eklenen her simge **tam olarak bir bit** alıyor: 5 simge 5,00 bit,
  6 simge 6,00 bit. Otuz bir simgelik gösterimde belirsizlik sıfır bittir, yani gösterim geri
  çevrilebilir olmuştur.
- Sıkı bileşim yaşam döngüsü sahipliği bildirir, gevşek bileşim bildirmez. Yaşam simgeleri
  yazılmadığında bir iş emrinin silinmesi 12 nesnelik sistemde 11 ayrı sonuçla uyumludur
  (1 ile 12 arası); yazıldığında sonuç tek değere iner: 6 silinen, 4 bağsız kalan nesne.
- Çokluk simgesi topluluğun varlığını söyler, içeriğini söylemez: dört parçalık katalogda üç
  kalemlik bir iş emrinin geçerli içerik sayısı sıralı ve tekrarlıysa 64, sırasız ve
  benzersizse 4 — on altı katlık aralık gösterimde tek bir `1:N` olarak durur.
- Simge başına bir bit yalnız ikili alanlar için geçerlidir. Yaşam alanı üç değerli olsaydı 20
  simgelik gösterime düşen sistem 15552 olurdu ve aynı beş simge 7,92 bit, yani simge başına
  1,58 bit alırdı.

## Sonraki Adım

Bu derste sayılan her şey durağandı: hangi tür neye bağlı, kaç tane, kim kimin yaşam döngüsünü
taşıyor. Sistemin çalışırken kaç ayrı parçaya bölündüğü hiç sorulmadı — beş bağın altı sınıfı
tek bir birimde de koşabilir, altı ayrı birimde de, ve otuz bir simgelik gösterim bunların
hiçbirini ayırt etmiyor.

Sonraki ders aynı sınıf kümesini çalışma zamanı birimlerine bölüyor ve bölüntüyü sayıyor: altı
sınıf kaç ayrı bileşen bölüntüsüne düşüyor, bir bileşen gösterimi bunların kaçını aynı çizime
indiriyor, ve bileşenler düğümlere yerleştirildiğinde hangi bağlar uzak bağ hâline geliyor.
