Gratis · Tanpa daftar · Mendukung file .mmd

Editor diagram kelas Mermaid

Diagram kelas memperlihatkan tipe-tipe dan hubungan di antaranya: apa memuat apa, apa mewarisi dari apa, apa bergantung pada apa. Cocok ketika intinya adalah bentuk kode — sebuah model domain, sebuah antarmuka perluasan, sebuah pohon pewarisan. Kalau Anda ingin menunjukkan apa yang terjadi saat program berjalan alih-alih bagaimana tipe-tipe itu berpasangan, pakailah diagram urutan.

Model domain pembayaran

Tiga macam hubungan dalam satu diagram: komposisi untuk bagian yang tidak hidup lebih lama daripada keseluruhannya, pewarisan untuk hierarki cara bayar, dan asosiasi biasa dengan kardinalitas. Maknanya terutama dibawa oleh panah; kotak-kotak kelas hampir cuma pelengkap.

classDiagram
    class Pesanan {
        +String nomor
        +StatusPesanan status
        +Uang total()
        +void tambahBaris(Produk p, int jumlah)
    }
    class BarisPesanan {
        +Produk produk
        +int jumlah
        +Uang nilai()
    }
    class CaraBayar {
        <<abstract>>
        +otorisasi(Uang jumlah) bool
    }
    class KartuKredit {
        +String empatDigitTerakhir
        +otorisasi(Uang jumlah) bool
    }
    class TransferBank {
        +String nomorRekening
        +otorisasi(Uang jumlah) bool
    }
    class BayarDiTempat {
        +Uang biayaPenanganan
        +otorisasi(Uang jumlah) bool
    }

    Pesanan "1" *-- "1..*" BarisPesanan : memuat
    Pesanan --> CaraBayar : dibayar dengan
    CaraBayar <|-- KartuKredit
    CaraBayar <|-- TransferBank
    CaraBayar <|-- BayarDiTempat
Buka ini di editor
Iklan

Contoh yang dibahas

1. Satu kelas

`+` berarti publik, `-` privat, `#` terlindung. Anggota yang bertanda kurung digambar sebagai metode; tanpa kurung ia sebuah medan.

classDiagram
    class Pengguna {
        +String surel
        -String cincangSandi
        +bool periksa(String calon)
    }
Buka di editor

2. Pewarisan dan antarmuka

`<|--` adalah pewarisan, dibaca «yang di kanan memperluas yang di kiri». Anotasi `<<interface>>` adalah label dan bukan perilaku, tetapi justru itulah yang menentukan diagramnya mudah dibaca atau tidak.

classDiagram
    class Repositori {
        <<interface>>
        +cari(String id) Entitas
        +simpan(Entitas e) void
    }
    class RepositoriPostgres {
        -Koneksi koneksi
        +cari(String id) Entitas
        +simpan(Entitas e) void
    }
    class RepositoriMemori {
        -Map penyimpanan
        +cari(String id) Entitas
        +simpan(Entitas e) void
    }
    Repositori <|.. RepositoriPostgres
    Repositori <|.. RepositoriMemori
Buka di editor

3. Komposisi lawan agregasi

Bedanya menyangkut masa hidup. Belah ketupat padat (`*--`) berarti bagiannya lenyap bersama keseluruhannya: hapus fakturnya, barisnya ikut hilang. Belah ketupat kosong (`o--`) berarti bagiannya berdiri sendiri.

classDiagram
    class Faktur {
        +String nomor
    }
    class BarisFaktur {
        +String keterangan
    }
    class Pelanggan {
        +String namaPerusahaan
    }
    Faktur "1" *-- "1..*" BarisFaktur : terdiri atas
    Pelanggan "1" o-- "0..*" Faktur : telah menerima
Buka di editor

4. Tipe generik

Tanda gelombang memberi parameter tipe: `Repositori~Pengguna~`. Penyarangan juga jalan, kadang perlu dan jarang merupakan gagasan bagus.

classDiagram
    class Repositori~T~ {
        +cari(String id) T
        +semua() List~T~
    }
    class Singgahan~K, V~ {
        +ambil(K kunci) V
        +taruh(K kunci, V nilai) void
    }
    class RepositoriPengguna {
        +cariLewatSurel(String surel) Pengguna
    }
    Repositori~Pengguna~ <|-- RepositoriPengguna
Buka di editor

5. Catatan dan arah

`direction LR` menata diagram dari kiri ke kanan, yang biasanya lebih menguntungkan pohon pewarisan daripada tata letak bawaan. Catatan adalah tempat yang tepat untuk batasan yang tidak muat di dalam kotak kelas.

classDiagram
    direction LR
    class PenyimpanPeristiwa {
        +tambahkan(Peristiwa p) void
        +putarUlang(String aliran) List~Peristiwa~
    }
    class Cuplikan {
        +int versi
        +byte[] isi
    }
    PenyimpanPeristiwa --> Cuplikan : menulis tiap 100 peristiwa
    note for PenyimpanPeristiwa "Hanya penambahan. Peristiwa tidak pernah diubah atau dihapus."
Buka di editor

Ringkasan sintaks diagram kelas

Panah hubungannya layak dihafal: panah itulah yang membedakan diagram kelas dari gambar kotak-dan-garis, dan panah itu dibaca dari kanan ke kiri, yang cukup lama menyesatkan.

SintaksArti
classDiagramMembuka diagram. Peka huruf besar-kecil.
class Nama { ... }Kelas beserta anggotanya. Kurung kurawal penutup pada baris tersendiri.
+anggotaPublik.
-anggotaPrivat.
#anggotaTerlindung.
+metode(Tipe arg) TipeKembalianMetode — justru tanda kurunglah yang menjadikannya metode.
<<interface>> / <<abstract>>Stereotipe, ditulis pada baris pertama di dalam kelas.
A <|-- BPewarisan: B memperluas A.
A <|.. BRealisasi: B mengimplementasikan antarmuka A.
A *-- BKomposisi: B tidak hidup lebih lama daripada A.
A o-- BAgregasi: B bisa ada tanpa A.
A --> BAsosiasi berarah.
A ..> BKetergantungan — A memakai B tetapi tidak menyimpannya.
A "1" --> "0..*" B : labelKardinalitas di kedua ujung ditambah label hubungan.
class Repo~T~Parameter tipe generik.
note for A "teks"Catatan yang dilekatkan pada sebuah kelas.
direction LRMengubah arah tata letak.
Iklan

Kesalahan yang merusak diagram kelas

Direproduksi pada Mermaid 11.12.2. Diagram kelas termasuk yang lebih toleran di antara keenam jenis, jadi separuh dari kesalahan ini tergambar dengan tenang dan memberi Anda gambar yang salah.

Yang Anda lihat

Parse error yang berakhir dengan: got 'EOF_IN_STRUCT'

Mengapa

Badan kelas dibuka dengan `{` dan tidak pernah ditutup. Kali ini nama tokennya benar-benar menolong: ia mengatakan berkasnya habis ketika kita masih berada di dalam sebuah kelas.

Solusi

Tutup kurung kurawalnya pada baris tersendiri.

Salah
classDiagram
    class Pesanan {
        +String nomor
Benar
classDiagram
    class Pesanan {
        +String nomor
    }

Yang Anda lihat

Parse error yang berakhir dengan: got 'ANNOTATION_END'

Mengapa

Panah dari diagram urutan dipakai di diagram kelas. `->>` di sini tidak berarti apa-apa, dan penguraiannya masuk cukup dalam sehingga mengembalikan nama token yang menyesatkan.

Solusi

Pakailah hubungan diagram kelas: `-->` untuk asosiasi, `<|--` untuk pewarisan, `*--` untuk komposisi.

Salah
classDiagram
    Pesanan ->> Pelanggan
Benar
classDiagram
    Pesanan --> Pelanggan : milik dari

Yang Anda lihat

No diagram type detected matching given configuration

Mengapa

Huruf besar-kecil kata kuncinya salah. `classdiagram` bukan `classDiagram`.

Solusi

Huruf D besar.

Salah
classdiagram
    class Pesanan
Benar
classDiagram
    class Pesanan

Yang Anda lihat

Panahnya menunjuk ke arah yang berlawanan dengan maksud Anda

Mengapa

Panah hubungan dibaca mundur dari mata panahnya. `A <|-- B` berarti B mewarisi dari A, bukan sebaliknya. Ditulis terbalik pun tetap tergambar — hanya saja sekarang ia menyatakan bahwa kelas dasarnya memperluas subkelasnya sendiri.

Solusi

Bacalah sebagai «ujung yang jauh memperluas ujung yang bermata panah». Taruh induknya di sebelah kiri `<|--`.

Salah
classDiagram
    KartuKredit <|-- CaraBayar
Benar
classDiagram
    CaraBayar <|-- KartuKredit

Yang Anda lihat

Muncul medan di tempat Anda mengharapkan metode

Mengapa

Tanda kurung adalah satu-satunya yang membedakan metode dari medan. `+simpan` adalah medan bernama simpan; `+simpan()` adalah metode. Kedua bentuk itu sah, jadi tidak ada yang memperingatkan.

Solusi

Tambahkan tanda kurungnya, lalu tipe kembaliannya kalau Anda ingin melihatnya.

Salah
classDiagram
    class Repo {
        +simpan
        +cari
    }
Benar
classDiagram
    class Repo {
        +simpan(Entitas e) void
        +cari(String id) Entitas
    }

Yang Anda lihat

Komposisi dan agregasi sekilas tampak sama dan mengatakan hal yang berlawanan

Mengapa

`*--` dan `o--` berbeda satu karakter, dan keduanya mengodekan perbedaan makna yang nyata: apakah bagiannya bisa hidup lebih lama daripada keseluruhannya. Memakai yang keliru menghasilkan diagram yang benar secara bentuk dan keliru terhadap domain Anda.

Solusi

Belah ketupat padat `*--` ketika menghapus induk berarti menghapus anak. Yang kosong `o--` ketika tidak.

Salah
classDiagram
    Pesanan o-- BarisPesanan : memuat
Benar
classDiagram
    Pesanan *-- BarisPesanan : memuat

Catatan tentang penggambaran

Diukur pada Mermaid 11.12.2, versi yang dipakai situs ini.

Ia tumbuh ke atas lebih cepat daripada jenis mana pun di sini

Diukur pada kelas-kelas beranggota dua, yang dirangkai dengan pewarisan: tiga kelas memberi viewBox sekitar 176×548, empat puluh kelas memberi 180×7726, yaitu kira-kira 194 piksel tinggi per kelas — pertambahan paling curam di antara keenam jenis di situs ini. Diagram empat puluh kelas melewati tujuh ribu piksel tinggi dan tidak terpakai sebagai satu gambar. `direction LR` menolong, tetapi di atas kira-kira lima belas kelas penyelesaian yang jujur adalah memecah diagramnya menurut batas domain.

Nama kelas harus dirangkai, labelnya tidak

Di sinilah bahasa Indonesia harus memilih gaya penulisan. Nama kelas adalah pengenal, jadi `Baris Pesanan` tidak bisa dipakai; ia harus dirangkai menjadi `BarisPesanan`. Untungnya bahasa Indonesia tidak memakai huruf di luar ASCII, jadi tidak ada kendala lain sama sekali — sudah diuji, `Pesanan` dan `BayarDiTempat` tergambar sebagaimana adanya. Sebagai imbalannya, label hubungan setelah titik dua adalah teks bebas, jadi `: dibayar dengan` ditulis biasa dengan spasi lengkap.

Jumlah anggota nyaris tidak memengaruhi lebar

Lebarnya ditentukan tanda tangan terpanjang dari satu anggota, bukan berapa banyak anggotanya. Kelas dengan dua puluh medan pendek tidak lebih lebar daripada kelas dengan tiga. Dengan kata lain: bermurah hatilah pada anggota dan berhematlah pada kelas, yang persis kebalikan dari naluri. Dalam bahasa Indonesia, satu nama metode berimbuhan panjang seperti `otorisasiPembayaranKartuKredit` sendirian menentukan lebar seluruh kelasnya.

Tipe generik memakai tanda gelombang dan itu ada akibatnya

`Repositori~T~` ditulis begitu karena tanda kurung sudut akan berbenturan dengan HTML di dalam label. Dari situ juga menyusul bahwa tanda gelombang sungguhan di dalam nama kelas atau nama anggota akan dibaca sebagai awal sebuah parameter tipe. Jarang terjadi, tetapi ketika terjadi cukup membingungkan.

Label berupa HTML, jadi ekspor PNG menggambar ulang

Label kelas digambar di dalam `<foreignObject>` pada SVG, dan peramban menolak merasterkannya ke atas kanvas. Ekspor PNG situs ini dulu gagal diam-diam dan mengembalikan berkas SVG; sekarang ia lebih dulu menggambar ulang diagramnya dengan label teks SVG biasa. PNG-nya keluar benar dan berukuran penuh, dengan tata huruf yang sedikit berbeda dari yang di layar.

Kapan diagram lain lebih cocok

Kalau Anda sedang mendokumentasikan basis data dan bukan sistem tipe, pakailah diagram ER. Pembedaannya penting: diagram kelas memodelkan perilaku dan pewarisan, yang tidak dimiliki tabel, sedangkan diagram ER memodelkan kunci dan kardinalitas dengan rapi, yang hanya disinggung sekilas oleh diagram kelas.

Kalau diagramnya sebagian besar berupa kotak yang disambung `-->` dan tanpa anggota, Anda sedang menggambar arsitektur dan bukan diagram kelas. Diagram alir dengan subgraf akan terlihat lebih baik dan mengklaim lebih sedikit.

Dan kalau daftar kelasnya lahir dari kode, pertimbangkan apakah diagramnya juga sebaiknya lahir dari sana. Diagram kelas yang dipelihara dengan tangan untuk basis kode yang berubah tiap minggu akan menjadi tidak benar dalam sebulan, dan diagram yang salah lebih mahal daripada tidak ada diagram.

Jenis diagram lain

Ditulis oleh Dominik Malsch · Terakhir diperbarui:

Buka editor →