"Dalam rekayasa perangkat lunak, class diagram dalam Unified Modeling Language (UML) adalah jenis diagram struktur statis yang menggambarkan struktur sistem dengan menunjukkan kelas-kelas sistem, atribut, operasi (atau method), dan hubungan antar objek."
-Wikipedia
- Class Diagram
- 1. Kelas (Class)
- 2. Atribut dan Method dalam Kelas
- 3. Relasi antar Kelas
- 4. Kardinalitas pada Relasi
- 5. Anotasi pada Kelas
- 6. Perbaikan
Class Diagram adalah salah satu jenis diagram dalam UML (Unified Modeling Language) yang digunakan untuk menggambarkan struktur statis suatu sistem. Diagram ini menunjukkan:
- Kelas (class)
- Atribut
- Metode / operasi
- Hubungan antar kelas
Class diagram banyak digunakan dalam pemodelan sistem berorientasi objek karena membantu menggambarkan bagaimana bagian-bagian sistem saling berhubungan. Fungsi dari class diagram:
- Merancang struktur sistem
- Memvisualisasikan hubungan antar objek
- Menjadi dasar pembuatan kode program
- Mempermudah komunikasi antara analis, desainer, dan programmer
- Mendokumentasikan sistem
Ada beberapa tools yang dapat kita gunakan untuk membuat Class Diagram:
- Mermaid.ai
- StarUML
- Draw.io
Berikut adalah contoh kode yang digunakan dalam modul ini: App.java
Class adalah blueprint atau cetakan dari objek. UML menyediakan mekanisme untuk merepresentasikan anggota kelas, seperti atribut dan metode, serta informasi tambahan tentangnya.
Satu kelas dalam diagram berisi tiga bagian:
- Bagian atas berisi Nama Kelas. Dicetak tebal dan rata tengah, dan huruf pertamanya dikapitalisasi. Ini juga dapat berisi teks anotasi opsional yang mendeskripsikan sifat kelas.
- Bagian tengah berisi Atribut Kelas. Rata kiri dan huruf pertamanya adalah huruf kecil.
- Bagian bawah berisi Metode yang dapat dieksekusi Kelas. Rata kiri dan huruf pertamanya juga huruf kecil.
Contoh:
Dalam Mermaid, ada dua cara untuk mendefinisikan sebuah kelas:
- Secara eksplisit menggunakan kata kunci class seperti
class Caryang akan mendefinisikan kelas Car. - Secara implisit melalui relasi (relationship) yang mendefinisikan dua kelas sekaligus beserta relasi. Misalnya,
Car <|-- HybridCar.
classDiagram
class Car
Car <|-- HybridCar
Dalam bahasa pemrograman Java, penamaan kelas mengikuti konvensi yang sangat baku agar kode tetap rapi, konsisten, dan mudah dipahami oleh sesama developer.
Berikut adalah aturan utama untuk konvensi penamaan kelas di Java:
- PascalCase (UpperCamelCase): Huruf pertama dari nama kelas harus selalu diawali dengan huruf kapital. Jika nama kelas terdiri dari beberapa kata, huruf pertama dari setiap kata berikutnya juga harus dikapitalisasi, tanpa ada spasi di antaranya.
- Kata Benda (Noun): Karena sebuah kelas pada dasarnya merepresentasikan sebuah objek atau entitas, gunakan kata benda atau frasa kata benda yang deskriptif.
- Deskriptif dan Jelas: Nama kelas harus dengan jelas mendeskripsikan tujuan atau apa yang diwakilinya. Usahakan menggunakan nama yang utuh dan hindari singkatan yang tidak umum (kecuali singkatan standar seperti URL, XML, atau HTML).
- Hindari Karakter Khusus: Meskipun Java secara teknis mengizinkan karakter seperti underscore (
_) atau tanda dolar ($), penggunaannya sangat tidak disarankan untuk nama kelas. Selain itu, Anda tidak boleh menggunakan karakter spasi.
Contoh Penerapan:
MahasiswaRekeningBankmahasiswa❌ (Diawali huruf kecil, ini adalah gaya penamaan untuk variabel atau objek).rekening_bank❌ (Menggunakan snake_case, yang mana tidak umum untuk penamaan di Java).HitungTotal❌ (Ini adalah frasa kata kerja, sehingga lebih cocok untuk nama method/fungsi).DataMhs❌ (Penggunaan singkatan yang bisa menimbulkan ambiguitas).
UML menyediakan mekanisme untuk merepresentasikan anggota kelas seperti atribut dan metode, serta informasi tambahan tentangnya. Dalam class diagram UML, atribut biasanya ditulis dengan format:
visibilitas namaAtribut : TipeData
Contoh:
+brand : String
-year : int
#price : double
Sedangkan metode ditulis dengan format:
visibilitas namaMethod(parameter: TipeData) TipeKembalian
Contoh:
#login()
+getName() String
+setName(name: String) void
+calculateTotal(price: double, qty: int) double
-withdraw(amount: double) boolean
Mermaid membedakan antara atribut dan fungsi/metode berdasarkan ada atau tidaknya tanda kurung (). Untuk mendefinisikan seluruh anggota kelas, kita menggunakan kurung kurawal {}.
classDiagram
class Car{
#brand : String
#type : String
#color : String
-speed : int
+startEngine() void
+getSpeed() int
+setSpeed(speed: int) void
+payToll(amount: int) void
}
Method digunakan untuk melakukan suatu tindakan, sehingga penamaannya harus merepresentasikan tindakan tersebut.
- lowerCamelCase: Huruf pertama harus diawali dengan huruf kecil. Jika nama method terdiri dari beberapa kata, huruf pertama dari kata kedua dan seterusnya harus dikapitalisasi.
- Kata Kerja (Verb): Karena method melakukan aksi, gunakan kata kerja atau frasa kata kerja.
- Pasangan yang Logis: Untuk method yang memanipulasi data, gunakan awalan standar seperti
get(mengambil nilai),set(mengubah nilai), atauis(untuk mengecek nilai boolean).
Contoh Penerapan:
hitungTotal()getDataMahasiswa()isMahasiswaAktif()HitungTotal()❌ (Diawali huruf kapital, menyerupai nama kelas).hitung_total()❌ (Menggunakan snake_case).dataMahasiswa()❌ (Kata benda, tidak mencerminkan tindakan/aksi).
Atribut / Variabel menyimpan status atau data.
- lowerCamelCase: Sama seperti method, nama variabel harus diawali dengan huruf kecil, dan kata berikutnya diawali dengan huruf kapital.
- Kata Benda (Noun): Nama variabel harus mendeskripsikan data apa yang disimpannya.
- Hindari Karakter Khusus: Jangan menggunakan karakter khusus (seperti
_atau$) di awal nama variabel. - Nama yang Deskriptif dan Bermakna: Hindari penggunaan variabel satu huruf (seperti
x,y,a,b) kecuali sebagai variabel counter sementara di dalam perulangan (loop).
Contoh Penerapan:
jumlahMahasiswahargaTotali,j,k(Hanya dapat diterima untuk indeks perulanganfor)JumlahMahasiswa❌ (Diawali huruf kapital).jmlhMhs❌ (Singkatan yang sulit dibaca/diucapkan).variabel1❌ (Tidak mendeskripsikan data yang disimpan).
| Return Type | Keterangan | Contoh |
|---|---|---|
void |
Method tidak mengembalikan nilai | +setName(name: String) void |
String |
Mengembalikan teks | +getName() String |
int |
Mengembalikan bilangan bulat | +getAge() int |
double |
Mengembalikan bilangan desimal | +getPrice() double |
boolean |
Mengembalikan nilai benar atau salah | +isActive() boolean |
char |
Mengembalikan satu karakter | +getGrade() char |
float |
Mengembalikan bilangan desimal presisi tunggal | +getScore() float |
long |
Mengembalikan bilangan bulat besar | +getPopulation() long |
Object |
Mengembalikan objek umum | +getData() Object |
Class |
Mengembalikan objek dari class tertentu | +getCustomer() Customer |
Array |
Mengembalikan array | +getScores() int[] |
List<T> |
Mengembalikan daftar data | +getStudents() List~Student~ |
Set<T> |
Mengembalikan kumpulan data unik | +getTags() Set~String~ |
Map<K,V> |
Mengembalikan pasangan key-value | +getSettings() Map~String,Integer~ |
| Simbol | Akses | Penjelasan |
|---|---|---|
+ |
Public | Dapat diakses dari mana saja, baik dari dalam class maupun dari class lain. |
- |
Private | Hanya dapat diakses dari dalam class itu sendiri. |
# |
Protected | Dapat diakses dari dalam class itu sendiri dan dari class turunan. |
~ |
Package/Internal | Dapat diakses oleh class lain yang masih berada dalam package yang sama. |
Kita juga dapat menyertakan classifiers tambahan ke definisi metode atau atribut dengan menambahkan notasi berikut ke bagian akhir metode atau atribut, yaitu: setelah () atau setelah return type:
| Simbol | Keterangan | Contoh |
|---|---|---|
* |
Abstrak (Abstract) | someAbstractMethod()* atau someAbstractMethod() int* |
$ |
Statis (Static) pada method | someStaticMethod()$ atau someStaticMethod() String$ |
$ |
Statis (Static) pada field | CONSTANT_FIELD: String$ |
classDiagram
class Car{
#brand : String
#type : String
#color : String
-speed : int
+startEngine() void*
+getSpeed() int
+setSpeed(speed: int) void
+payToll(amount: int) void
}
Constructor adalah method khusus yang digunakan untuk membuat atau menginisialisasi objek dari sebuah class. Constructor tidak wajib ditampilkan dalam class diagram.
Constructor perlu ditampilkan jika:
- penting untuk menunjukkan cara objek dibuat
- class memiliki lebih dari satu constructor
- diagram digunakan sampai tahap implementasi
- parameter constructor perlu dijelaskan
Constructor tidak perlu ditampilkan jika:
- diagram masih bersifat konsep atau analisis
- fokus diagram adalah struktur class dan hubungan antar class
- constructor tidak memberi informasi tambahan yang penting
classDiagram
class Car{
#brand : String
#type : String
#color : String
-speed : int
+Car()
+Car(brand: String, type: String, color: String, speed: int)
+startEngine() void*
+getSpeed() int
+setSpeed(speed: int) void
+payToll(amount: int) void
}
Konstanta adalah variabel yang nilainya tetap dan tidak dapat diubah (dideklarasikan dengan keyword static final).
Konvensi Penamaan:
- UPPER_SNAKE_CASE: Semua huruf harus KAPITAL.
- Underscore (
_): Jika terdiri dari beberapa kata, pisahkan setiap kata menggunakan karakter garis bawah (underscore).
Contoh Penerapan:
MAKSIMUM_KAPASITASNILAI_PISTATUS_AKTIFMaksimumKapasitas❌ (Menggunakan PascalCase).maksimum_kapasitas❌ (Huruf kecil semua).
Pada Mermaid, tambahkan $ di akhir tipe data (lihat bagian Classifiers)
Relasi (Relationship) adalah istilah umum yang mencakup jenis koneksi logis tertentu yang ditemukan pada diagram kelas dan objek.
[kelasA][Panah][KelasB]
Ada delapan jenis relasi berbeda yang didefinisikan untuk kelas di bawah UML yang saat ini didukung oleh Mermaid:
| Type | Description |
|---|---|
<|-- |
Inheritance |
*-- |
Composition |
o-- |
Aggregation |
--> |
Association |
-- |
Link (Solid) |
..> |
Dependency |
..|> |
Realization |
.. |
Link (Dashed) |
classDiagram
Kendaraan <|-- Mobil
Rumah *-- Ruangan
Tim o-- Pemain
Siswa --> Kelas
Dokter -- Pasien
Struk ..> Printer
Pembayaran <|.. TransferBank
Admin .. Laporan
| Jenis Relationship | Penjelasan |
|---|---|
| Inheritance | Kelas anak mewarisi sifat dari kelas induk. |
| Composition | Satu objek terdiri dari objek lain, dan bagian itu ikut hilang jika induknya dihapus. |
| Aggregation | Satu objek memiliki objek lain, tetapi objek itu masih bisa berdiri sendiri. |
| Association | Dua kelas saling berhubungan atau saling menggunakan. |
| Link (Solid) | Hubungan umum antar kelas. |
| Dependency | Satu kelas bergantung pada kelas lain. |
| Realization | Kelas menerapkan interface. |
| Link (Dashed) | Hubungan umum tidak langsung antar kelas. |
Kita dapat menambahkan label untuk menggambarkan sifat relasi antara dua kelas. Selain itu, mata panah dapat digunakan dalam arah yang berlawanan juga.
[kelasA][Panah][KelasB]: TeksLabel
classDiagram
Kendaraan <|-- Mobil: Inheritance
Rumah *-- Ruangan: Composition
Tim o-- Pemain: Aggregation
Siswa --> Kelas: Association
Dokter -- Pasien: Link (Solid)
Struk ..> Printer: Dependency
Pembayaran <|.. TransferBank: Realization
Admin .. Laporan: Link (Dashed)
Jika kita hubungkan dengan studi kasus mobil, maka diagram kelasnya adalah sebagai berikut:
classDiagram
Car <|-- ElectricCar
TollPayment <|.. CashPayment
Car --> CashPayment: menggunakan
class Car{
#brand : String
#type : String
#color : String
-speed : int
#cashPayment : CashPayment
+Car()
+Car(brand: String, type: String, color: String, speed: int)
+startEngine() void*
+getSpeed() int
+setSpeed(speed: int) void
+payToll(amount: int) void
}
class ElectricCar {
+ElectricCar(brand: String, type: String, color: String, speed: int)
+startEngine() void
}
class TollPayment {
+payToll(amount: int) void
}
class CashPayment {
+payToll(amount: int) void
}
Mengapa relasi antara Car dan CashPayment adalah association?
- Walaupun di Java, hubungan Car dan CashPayment tampak seperti composition karena satu objek menyimpan objek lain sebagai atribut, di UML belum tentu itu composition. Kita perlu melihat dari konteks objeknya.
- Dalam case ini, hubungan Car dan CashPayment adalah asosiasi, karena CashPayment bukan bagian penyusun Car. CashPayment hanyalah cara bayar yang digunakan mobil atau pemiliknya.
| Jenis Relasi | Definisi | Kepemilikan | Ketergantungan Objek | Contoh |
|---|---|---|---|---|
| Association | Dua kelas saling berhubungan | Tidak menandakan kepemilikan | Objek bisa berdiri sendiri | Customer --> Order |
| Aggregation | Satu objek memiliki objek lain | Kepemilikan lemah | Objek bagian tetap bisa ada walau induknya dihapus | Team o-- Player |
| Composition | Satu objek terdiri dari bagian-bagian penting | Kepemilikan kuat | Objek bagian ikut hilang jika induknya dihapus | House *-- Room |
Relasi dua arah adalah hubungan antara dua kelas yang saling terhubung dan saling mengetahui. Relasi ini digunakan ketika hubungan penting dilihat dari kedua sisi.
Contoh case:
- Mahasiswa mengetahui MataKuliah
- MataKuliah mengetahui Mahasiswa
classDiagram
Mahasiswa <--> MataKuliah : mengetahui
Sedangkan jika relasi satu arah, hubungan antara dua kelas yang hanya diketahui oleh satu sisi saja. Relasi ini digunakan ketika hanya satu kelas yang perlu berhubungan langsung dengan kelas lain.
Contoh case:
- Kasir mencetak Struk
classDiagram
Kasir --> Struk : mencetak
| Aspek | Relasi Satu Arah | Relasi Dua Arah |
|---|---|---|
| Arah hubungan | Hanya satu sisi | Kedua sisi |
| Referensi | Satu kelas mengetahui kelas lain | Kedua kelas saling mengetahui |
| Kompleksitas | Lebih sederhana | Lebih kompleks |
| Penggunaan | Jika hubungan cukup dilihat dari satu sisi | Jika hubungan penting dilihat dari dua sisi |
Multiplisitas atau kardinalitas dalam diagram kelas menunjukkan jumlah instansiasi objek dari satu kelas yang dapat dihubungkan dengan instansiasi objek dari kelas lainnya. Notasi kardinalitas ditempatkan di dekat akhir dari suatu relasi.
| Kardinalitas | Arti |
|---|---|
1 |
Hanya 1 |
0..1 |
Nol atau satu |
1..* |
Satu atau lebih |
* |
Banyak (many) |
n |
Sebanyak n, dengan n > 1 |
0..n |
Nol hingga n, dengan n > 1 |
1..n |
Satu hingga n, dengan n > 1 |
Kardinalitas dapat dengan mudah ditentukan dengan menempatkan opsi teks dalam tanda kutip " sebelum atau sesudah panah tertentu.
[kelasA] "kardinalitas1" [Panah] "kardinalitas2" [KelasB]:TeksLabel
Tidak semua relasi memiliki kardinalitas. Berikut adalah penjelasan untuk setiap relasinya.
| Relasi | Bisa pakai cardinality? | Keterangan |
|---|---|---|
| Association | Ya | Paling umum digunakan untuk menunjukkan jumlah hubungan antar objek |
| Aggregation | Ya | Karena aggregation adalah bentuk khusus dari association |
| Composition | Ya | Karena composition juga bentuk khusus dari association |
| Inheritance | Tidak | Karena ini hubungan pewarisan, bukan jumlah keterhubungan objek |
| Realization | Tidak | Karena ini hubungan implementasi interface |
| Dependency | Biasanya tidak | Karena hanya menunjukkan ketergantungan/pemakaian |
| Link (Solid) | Bisa, jika dipakai sebagai association umum | Tergantung konteks diagram |
| Link (Dashed) | Biasanya tidak | Umumnya bukan untuk multiplicity |
Contoh:
classDiagram
Customer "1" --> "0..*" Order : membuat
Team "1" o-- "1..*" Player : memiliki
House "1" *-- "1..*" Room : terdiri dari
Jika kita hubungkan dengan studi kasus mobil, maka diagram kelasnya adalah sebagai berikut:
classDiagram
Car <|-- ElectricCar
TollPayment <|.. CashPayment
Car "1" --> "1" CashPayment: menggunakan
class Car{
#brand : String
#type : String
#color : String
-speed : int
#cashPayment : CashPayment
+Car()
+Car(brand: String, type: String, color: String, speed: int)
+startEngine() void*
+getSpeed() int
+setSpeed(speed: int) void
+payToll(amount: int) void
}
class ElectricCar {
+ElectricCar(brand: String, type: String, color: String, speed: int)
+startEngine() void
}
class TollPayment {
+payToll(amount: int) void
}
class CashPayment {
+payToll(amount: int) void
}
Kita bisa membubuhi keterangan (anotasi) pada kelas dengan penanda untuk memberikan keterangan tambahan tentang kelas tersebut. Beberapa anotasi yang umum meliputi:
| Anotasi | Keterangan |
|---|---|
<<Interface>> |
Untuk merepresentasikan kelas interface (antarmuka) |
<<Abstract>> |
Untuk merepresentasikan kelas abstrak |
<<Service>> |
Untuk merepresentasikan kelas layanan (service) |
<<Enumeration>> |
Untuk merepresentasikan enum |
Anotasi didefinisikan di dalam << pembuka dan >> penutup. Ada tiga cara untuk menambahkan anotasi ke sebuah kelas, dan dalam semua kasus outputnya akan sama:
-
Sejajar (Inline) dengan definisi kelas:
classDiagram class Shape <<interface>> -
Dalam baris terpisah setelah kelas didefinisikan:
classDiagram class Shape <<interface>> Shape Shape : noOfVertices Shape : draw() -
Dalam struktur bersarang (nested) bersama dengan definisi kelas:
classDiagram class Shape{ <<interface>> noOfVertices draw() } class Color{ <<enumeration>> RED BLUE GREEN WHITE BLACK }
Jika kita hubungkan dengan studi kasus mobil, maka diagram kelasnya adalah sebagai berikut:
classDiagram
Car <|-- ElectricCar
TollPayment <|.. CashPayment
Car "1" --> "1" CashPayment: menggunakan
class Car{
#brand : String
#type : String
#color : String
-speed : int
#cashPayment : CashPayment
+Car()
+Car(brand: String, type: String, color: String, speed: int)
+startEngine() void*
+getSpeed() int
+setSpeed(speed: int) void
+payToll(amount: int) void
}
class ElectricCar {
+ElectricCar(brand: String, type: String, color: String, speed: int)
+startEngine() void
}
class TollPayment {
+payToll(amount: int) void
}
class CashPayment {
+payToll(amount: int) void
}
<<Abstract>> Car
<<Interface>> TollPayment
Interface mendefinisikan kontrak yang harus diikuti oleh kelas yang mengimplementasikannya.
- PascalCase (UpperCamelCase): Sama seperti penamaan Kelas, diawali dengan huruf kapital.
- Kata Sifat (Adjective) atau Kata Benda: Tergantung pada tujuannya. Seringkali interface berakhiran dengan
-ableatau-iblejika mendefinisikan sebuah kemampuan.
Contoh Penerapan:
Runnable(Kata sifat/kemampuan)Serializable(Kata sifat/kemampuan)Kendaraan(Kata benda, jika interface mendefinisikan entitas abstrak)DapatTerbangrunnable❌ (Diawali huruf kecil).aksiBerjalan❌ (Menyerupai nama method).
classDiagram
Car <|-- ElectricCar
TollPayment <|.. CashPayment
Car "1" --> "1" TollPayment : menggunakan
class Car {
<<Abstract>>
#brand: String
#type: String
#color: String
-speed: int
#tollPayment: TollPayment
+Car()
+Car(brand: String, type: String, color: String, speed: int, tollPayment: TollPayment)
+startEngine() void*
+getSpeed() int
+setSpeed(speed: int) void
+payToll(amount: int) void
}
class ElectricCar {
+ElectricCar(brand: String, type: String, color: String, speed: int, tollPayment: TollPayment)
+startEngine() void
}
class TollPayment {
<<Interface>>
+payToll(amount: int) void
}
class CashPayment {
+payToll(amount: int) void
}
Perbaikan
-
Relasi
Car --> CashPaymentdiganti jadiCar --> TollPaymentKalau
CashPaymentadalah implementasi dariTollPayment, makaCarsebaiknya bergantung pada interfaceTollPayment, bukan langsung keCashPayment. Ini lebih fleksibel dan lebih sesuai OOP. -
Atribut
cashPaymentdiganti jaditollPayment: TollPaymentAtribut di abstract class sebaiknya memakai tipe interface, supaya nanti bisa diganti dengan implementasi lain seperti:
CashPaymentCardPaymentEmoneyPayment
-
Constructor diperbaiki
Sebelumnya constructor
CardanElectricCarbelum menerima objek pembayaran, padahal class punya atribut pembayaran.Diubah menjadi:
+Car(brand: String, type: String, color: String, speed: int, tollPayment: TollPayment)dan
+ElectricCar(brand: String, type: String, color: String, speed: int, tollPayment: TollPayment)
Hasil perbaikan di atas bisa diakses pada kode berikut: AppFinal.java
Sifat: Tugas Individu
-
Cari case / problem di sekitar Anda yang bisa diselesaikan dengan paradigma OOP
-
Rancanglah Class Diagram-nya menggunakan Mermaid.ai
-
Setelah itu, coba implementasikan ke kode Java
-
Buatkan dokumentasi di Github Markdown, mencakup hal-hal berikut:
- Deskripsi kasus
- Class diagram
- Kode program Java
- Screenshot output
- Penjelasan prinsip-prinsip OOP apa saja yang diterapkan
- Penjelasan keunikan yang membedakan dengan individu lain
-
Setiap mahasiswa harus menonjolkan keunikan dari program yang dibuatnya
-
Code akan dicek similarity antar individu dan AI-generated percentage-nya
-
Selamat mengerjakan dan berlibur :)











