Mermaid sınıf diyagramı editörü
Sınıf diyagramı tipleri ve aralarındaki ilişkileri gösterir: ne neyi içeriyor, ne neyden türüyor, ne neye bağımlı. Asıl konu kodun biçimiyse uygundur — bir alan modeli, bir eklenti arayüzü, bir kalıtım ağacı. Tipler nasıl uyuşuyor değil de çalışma anında ne oluyor sorusunu anlatmak istiyorsanız sıra diyagramı kullanın.
Ödeme alanının modeli
Tek diyagramda üç ilişki türü: bütünden ayrı yaşayamayan parçalar için birleşim, ödeme yöntemleri hiyerarşisi için kalıtım ve çokluk taşıyan sıradan bir ilişkilendirme. Anlamı asıl taşıyan oklardır; sınıf kutuları neredeyse yan üründür.
classDiagram
class Sipariş {
+String numara
+SiparişDurumu durum
+Tutar toplam()
+void satırEkle(Ürün ürün, int adet)
}
class SiparişSatırı {
+Ürün ürün
+int adet
+Tutar tutar()
}
class ÖdemeYöntemi {
<<abstract>>
+provizyonAl(Tutar tutar) bool
}
class KrediKartı {
+String son4Hane
+provizyonAl(Tutar tutar) bool
}
class Havale {
+String iban
+provizyonAl(Tutar tutar) bool
}
class KapıdaÖdeme {
+Tutar tahsilatBedeli
+provizyonAl(Tutar tutar) bool
}
Sipariş "1" *-- "1..*" SiparişSatırı : içerir
Sipariş --> ÖdemeYöntemi : şununla ödenir
ÖdemeYöntemi <|-- KrediKartı
ÖdemeYöntemi <|-- Havale
ÖdemeYöntemi <|-- KapıdaÖdemeÇözümlü örnekler
1. Tek sınıf
`+` genel, `-` özel, `#` korumalıdır. Parantezli üye metot olarak çizilir; parantezsiz olan alandır.
classDiagram
class Kullanıcı {
+String eposta
-String parolaÖzeti
+bool doğrula(String aday)
}2. Kalıtım ve arayüzler
`<|--` kalıtımdır, «sağdaki soldakini genişletir» diye okunur. `<<interface>>` bir davranış değil bir etikettir, ama diyagramın okunurluğunu belirleyen odur.
classDiagram
class Depo {
<<interface>>
+bul(String id) Varlık
+kaydet(Varlık v) void
}
class PostgresDepo {
-Bağlantı bağlantı
+bul(String id) Varlık
+kaydet(Varlık v) void
}
class BellekDepo {
-Map depo
+bul(String id) Varlık
+kaydet(Varlık v) void
}
Depo <|.. PostgresDepo
Depo <|.. BellekDepo3. Birleşim ile toplanma arasındaki fark
Fark yaşam süresiyle ilgilidir. Dolu baklava (`*--`) parçanın bütünle birlikte yok olduğunu söyler: faturayı silin, satırları da gider. Boş baklava (`o--`) parçanın bağımsız var olduğunu söyler.
classDiagram
class Fatura {
+String numara
}
class FaturaSatırı {
+String açıklama
}
class Cari {
+String unvan
}
Fatura "1" *-- "1..*" FaturaSatırı : oluşur
Cari "1" o-- "0..*" Fatura : kesti4. Jenerik tipler
Tilde işaretleri tip parametresi verir: `Depo~Kullanıcı~`. İç içe geçirmek de çalışır, bazen gereklidir ve nadiren iyi bir fikirdir. Türkçe harfler jenerik tipin içinde sorunsuz çalışır.
classDiagram
class Depo~T~ {
+bul(String id) T
+tümü() List~T~
}
class Önbellek~K, V~ {
+getir(K anahtar) V
+koy(K anahtar, V değer) void
}
class KullanıcıDeposu {
+epostayaGöreBul(String eposta) Kullanıcı
}
Depo~Kullanıcı~ <|-- KullanıcıDeposu5. Notlar ve yön
`direction LR` diyagramı soldan sağa dizer; kalıtım ağaçlarına genellikle öntanımlı düzenden daha çok yarar. Not ise sınıf kutusuna sığmayan kısıtın doğru yeridir.
classDiagram
direction LR
class OlayDeposu {
+ekle(Olay o) void
+yenidenOynat(String akış) List~Olay~
}
class AnlıkGörüntü {
+int sürüm
+byte[] içerik
}
OlayDeposu --> AnlıkGörüntü : her 100 olayda bir yazar
note for OlayDeposu "Yalnızca ekleme. Olaylar hiçbir zaman değiştirilmez ya da silinmez."Sınıf diyagramı sözdizimi özeti
Ezberlenmeye değer olan ilişki oklarıdır: sınıf diyagramını kutu-çizgi resminden ayıran onlardır ve uzun süre yanıltacak biçimde sağdan sola okunurlar.
| Sözdizimi | Anlamı |
|---|---|
| classDiagram | Diyagramı açar. Büyük-küçük harfe duyarlıdır ve noktalı i ister. |
| class Ad { ... } | Üyeleriyle birlikte sınıf. Kapanış süslü parantezi ayrı satırda. |
| +üye | Genel. |
| -üye | Özel. |
| #üye | Korumalı. |
| +metot(Tip arg) DönüşTipi | Metot — onu metot yapan şey parantezlerdir. |
| <<interface>> / <<abstract>> | Stereotip, sınıfın içinde ilk satıra yazılır. |
| A <|-- B | Kalıtım: B, A'yı genişletir. |
| A <|.. B | Gerçekleme: B, A arayüzünü uygular. |
| A *-- B | Birleşim: B, A'dan sonra yaşamaz. |
| A o-- B | Toplanma: B, A olmadan da var olabilir. |
| A --> B | Yönlü ilişkilendirme. |
| A ..> B | Bağımlılık — A, B'yi kullanır ama tutmaz. |
| A "1" --> "0..*" B : etiket | İki uçta çokluk ve ilişki etiketi. |
| class Depo~T~ | Jenerik tip parametresi. |
| note for A "metin" | Sınıfa iliştirilmiş not. |
| direction LR | Yerleşim yönünü değiştirir. |
Sınıf diyagramını bozan hatalar
Mermaid 11.12.2 üzerinde yeniden üretildi. Sınıf diyagramı altı tip içinde hoşgörülü olanlardandır, bu yüzden aşağıdakilerin yarısı sessizce çizilir ve size yanlış resmi verir.
Ne görüyorsunuz
No diagram type detected matching given configuration
Neden
Anahtar sözcükte noktasız ı var. Türkçe klavyede I tuşu noktasız ı ürettiği için `classDıagram` yazmak son derece kolaydır ve ekranda doğrusundan neredeyse ayırt edilemez. Ölçüldü: `classDıagram` ve `stateDıagram-v2` bu hatayı verir, doğru yazımları ise sorunsuz çizilir. Aynı satır büyük-küçük harfe de duyarlıdır: `classdiagram` da çalışmaz.
Çözüm
Anahtar sözcüğü noktalı i ve büyük D ile yazın. Sınıf ve üye adlarında Türkçe harfler tamamen serbesttir.
classDıagram
class Sipariş {
+String numara
}classDiagram
class Sipariş {
+String numara
}Ne görüyorsunuz
Parse error, sonu: got 'EOF_IN_STRUCT'
Neden
`{` ile açılmış ve hiç kapanmamış bir sınıf gövdesi. Bu kez belirteç adı gerçekten yardımcı olur: hâlâ sınıfın içindeyken dosyanın bittiğini söyler.
Çözüm
Süslü parantezi ayrı bir satırda kapatın.
classDiagram
class Sipariş {
+String numaraclassDiagram
class Sipariş {
+String numara
}Ne görüyorsunuz
Parse error, sonu: got 'ANNOTATION_END'
Neden
Sıra diyagramının oku sınıf diyagramında kullanılmış. `->>` burada hiçbir şey ifade etmez; ayrıştırıcı içine yeterince girdiği için de yanıltıcı bir belirteç adı döndürür.
Çözüm
Sınıf diyagramının ilişkilerini kullanın: ilişkilendirme için `-->`, kalıtım için `<|--`, birleşim için `*--`.
classDiagram
Sipariş ->> MüştericlassDiagram
Sipariş --> Müşteri : şuna aittirNe görüyorsunuz
Ok istediğinizin tersine bakıyor
Neden
İlişki okları uçtan geriye doğru okunur. `A <|-- B`, B'nin A'dan türediğini söyler, tersini değil. Ters yazarsanız yine çizilir — yalnızca artık taban sınıfın kendi alt sınıfını genişlettiğini iddia eder.
Çözüm
«Uzak uç, uçlu tarafı genişletir» diye okuyun. Ana sınıfı `<|--` işaretinin soluna koyun.
classDiagram
KrediKartı <|-- ÖdemeYöntemiclassDiagram
ÖdemeYöntemi <|-- KrediKartıNe görüyorsunuz
Metot beklediğiniz yerde alan beliriyor
Neden
Metodu alandan ayıran tek şey parantezlerdir. `+kaydet` kaydet adlı bir alandır; `+kaydet()` bir metottur. İki biçim de geçerli olduğu için hiçbir uyarı gelmez.
Çözüm
Parantezleri ekleyin, görmek istiyorsanız ardından dönüş tipini yazın.
classDiagram
class Depo {
+kaydet
+bul
}classDiagram
class Depo {
+kaydet(Varlık v) void
+bul(String id) Varlık
}Ne görüyorsunuz
Birleşim ile toplanma ilk bakışta aynı görünür, tersini söylerler
Neden
`*--` ile `o--` tek karakterle ayrılır ve gerçek bir anlam farkını kodlar: parça bütünden sonra yaşayabilir mi. Yanlışını kullanmak biçimsel olarak doğru, alanınız açısından yanlış bir diyagram üretir.
Çözüm
Üstü silmek alttakini de siliyorsa dolu baklava `*--`. Silmiyorsa boş baklava `o--`.
classDiagram
Sipariş o-- SiparişSatırı : içerirclassDiagram
Sipariş *-- SiparişSatırı : içerirÇizim üzerine notlar
Bu sitenin kullandığı Mermaid 11.12.2 üzerinde ölçüldü.
Buradaki her tipten daha hızlı yukarı büyür
İkişer üyeli, kalıtımla bağlanmış sınıflar üzerinde ölçüldü: üç sınıf yaklaşık 176×548 viewBox verir, kırk sınıf 180×7726 — yani sınıf başına yaklaşık 194 piksel yükseklik. Bu sitedeki altı tip içindeki en dik artış budur. Kırk sınıflık bir diyagram yedi bin pikseli aşar ve tek resim olarak kullanışsızdır. `direction LR` yardımcı olur, ama aşağı yukarı on beş sınıftan sonra dürüst çözüm diyagramı alan sınırlarına göre bölmektir.
Üye sayısı genişliği neredeyse hiç etkilemez
Genişliği kaç üye olduğu değil, tek bir üyenin en uzun imzası belirler. Yirmi kısa alanı olan bir sınıf, üç alanı olandan geniş değildir. Başka bir deyişle: üyelerde cömert, sınıflarda cimri olabilirsiniz — ki bu, ilk refleksin tam tersidir. Türkçede imzalar eklerle uzadığı için genişliği genellikle açıklayıcı adı olan tek bir metot belirler.
Türkçe harfler her yerde çalışır, jenerik tiplerin içinde de
Sınandı: `Sipariş`, `parolaÖzeti`, `SiparişSatırı` ve `KapıdaÖdeme` sınıf ve üye adı olarak çalışır; `Depo~Kullanıcı~` da hatasız dizilir. Modelinizi çizdirmek için Türkçe harflerden arındırmanız gerekmez. Tek gerçek kısıt tildedir, çünkü o sözdizimidir. Dikkat edilecek yer yalnızca ilk satırdaki anahtar sözcüktür: gövdede noktasız ı serbest, `classDıagram`da ölümcüldür.
Jenerik tipler tilde kullanır ve bunun bir sonucu vardır
`Depo~T~` böyle görünür, çünkü açılı ayraçlar etiketlerdeki HTML ile çakışırdı. Bundan şu da çıkar: sınıf ya da üye adındaki gerçek bir tilde tip parametresinin başlangıcı sanılır. Nadirdir, ama olduğunda insanı hatırı sayılır biçimde şaşırtır.
Etiketler HTML olduğu için PNG dışa aktarımı yeniden çizer
Sınıf etiketleri SVG içindeki `<foreignObject>` içinde çizilir ve tarayıcılar bunu canvas üzerine rasterlemeyi reddeder. Bu sitenin PNG dışa aktarımı önceden sessizce başarısız olup SVG dosyası veriyordu; artık diyagramı önce düz SVG metin etiketleriyle yeniden çiziyor. PNG doğru ve tam boyutta çıkıyor, dizgisi ekrandakinden az bir farkla.
Başka bir diyagramın daha uygun olduğu durumlar
Tip sistemini değil veritabanını belgeliyorsanız ER diyagramı kullanın. Ayrım önemlidir: sınıf diyagramları tabloların sahip olmadığı davranışı ve kalıtımı modeller, ER diyagramları ise sınıf diyagramlarının üstünkörü geçtiği anahtarları ve çoklukları düzgün modeller.
Diyagram ağırlıkla `-->` ile bağlanmış, üyesiz kutulardan oluşuyorsa sınıf diyagramı değil mimari çiziyorsunuz demektir. Alt gruplu bir akış şeması hem daha iyi görünür hem daha az şey iddia eder.
Sınıf listesi koddan çıkıyorsa, diyagramın da oradan çıkması gerekip gerekmediğini düşünün. Her hafta değişen bir kod tabanı için elle bakılan bir sınıf diyagramı bir ayda gerçek dışı olur; yanlış diyagramın bedeli ise diyagramsızlıktan yüksektir.
Diğer diyagram türleri
Yazan Dominik Malsch · Son güncelleme: