Komposisi, Agregasi, dan Asosiasi di Jawa

1. Perkenalan

Objek memiliki hubungan di antara mereka, baik dalam kehidupan nyata maupun dalam pemrograman. Terkadang sulit untuk memahami atau menerapkan hubungan ini.

Dalam tutorial ini, kita akan fokus pada penggunaan Java pada tiga jenis hubungan yang terkadang mudah tercampur: komposisi, agregasi, dan asosiasi.

2. Komposisi

Komposisi adalah jenis hubungan "milik". Artinya salah satu objek adalah struktur yang secara logis lebih besar, yang berisi objek lainnya. Dengan kata lain, itu bagian atau anggota dari objek lain.

Alternatifnya, kita sering menyebutnya sebagai hubungan "has-a" (sebagai lawan dari hubungan "is-a", yang merupakan warisan).

Misalnya sebuah ruangan adalah milik sebuah gedung, atau dengan kata lain sebuah gedung memiliki sebuah ruangan. Jadi pada dasarnya, apakah kita menyebutnya "milik-milik" atau "memiliki-a" hanyalah masalah sudut pandang.

Komposisi adalah jenis hubungan "has-a" yang kuat karena objek di dalamnya memilikinya. Oleh karena itu, siklus hidup objek terikat. Artinya jika kita menghancurkan objek pemiliknya, anggotanya juga akan ikut hancur bersamanya. Misalnya, ruangan dihancurkan dengan bangunan pada contoh kita sebelumnya.

Perhatikan itu tidak berarti, bahwa objek yang mengandung tidak bisa ada tanpa bagiannya. Misalnya, kita bisa merobohkan semua dinding di dalam sebuah bangunan, sehingga menghancurkan ruangan-ruangan itu. Tapi bangunan itu akan tetap ada.

Dari segi kardinalitas, suatu objek penampung dapat memiliki bagian sebanyak yang kita inginkan. Namun, semua bagian harus memiliki tepat satu wadah .

2.1. UML

Di UML, kami menunjukkan komposisi dengan simbol berikut:

Perhatikan, berlian berada di objek penampung dan merupakan dasar garis, bukan mata panah. Demi kejelasan, kami juga sering menggambar panah:

Jadi, kita bisa menggunakan konstruksi UML ini untuk contoh Ruang Gedung kita:

2.2. Kode sumber

Di Java, kita dapat memodelkannya dengan kelas dalam non-statis:

class Building { class Room {} }

Alternatifnya, kita bisa mendeklarasikan kelas itu dalam tubuh metode juga. Tidak masalah apakah itu kelas bernama, kelas anonim atau lambda:

class Building { Room createAnonymousRoom() { return new Room() { @Override void doInRoom() {} }; } Room createInlineRoom() { class InlineRoom implements Room { @Override void doInRoom() {} } return new InlineRoom(); } Room createLambdaRoom() { return () -> {}; } interface Room { void doInRoom(); } }

Perhatikan, bahwa itu penting, kelas dalam kita harus non-statis karena mengikat semua instance-nya ke kelas yang memuatnya.

Biasanya, objek yang mengandung ingin mengakses anggotanya. Oleh karena itu, kita harus menyimpan referensi mereka:

class Building { List rooms; class Room {} }

Perhatikan, bahwa semua objek kelas dalam menyimpan referensi implisit ke objek yang memuatnya. Akibatnya, kami tidak perlu menyimpannya secara manual untuk mengaksesnya:

class Building { String address; class Room { String getBuildingAddress() { return Building.this.address; } } }

3. Agregasi

Agregasi juga merupakan hubungan "memiliki". Yang membedakan dengan komposisi, tidak ada yang namanya kepemilikan. Akibatnya, siklus hidup objek tidak terikat: setiap objek dapat eksis secara independen satu sama lain.

Misalnya mobil dan rodanya. Kita bisa melepas roda, dan roda itu akan tetap ada. Kami dapat memasang roda lain (yang sudah ada sebelumnya), atau memasangnya ke mobil lain dan semuanya akan bekerja dengan baik.

Tentu saja, mobil tanpa roda atau roda yang terlepas tidak akan berguna seperti mobil dengan roda yang terpasang. Tapi itulah mengapa hubungan ini ada di tempat pertama: untuk mengumpulkan bagian-bagian menjadi konstruksi yang lebih besar, yang mampu melakukan lebih banyak hal daripada bagian-bagiannya .

Karena agregasi tidak melibatkan kepemilikan, anggota tidak perlu terikat hanya ke satu penampung . Misalnya segitiga terbuat dari ruas-ruas. Tetapi segitiga dapat berbagi segmen sebagai sisinya.

3.1. UML

Agregasi sangat mirip dengan komposisi. Satu-satunya perbedaan logis adalah agregasi adalah hubungan yang lebih lemah.

Oleh karena itu, representasi UML juga sangat mirip. Satu-satunya perbedaan adalah berlian itu kosong:

Untuk mobil dan roda, kami akan melakukan:

3.2. Kode sumber

Di Java, kita dapat memodelkan agregasi dengan referensi lama yang biasa:

class Wheel {} class Car { List wheels; }

Anggota dapat berupa semua jenis kelas, kecuali kelas dalam yang tidak statis.

Dalam cuplikan kode di atas, kedua kelas memiliki file sumber yang terpisah. Namun, kita juga bisa menggunakan kelas dalam statis:

class Car { List wheels; static class Wheel {} }

Perhatikan bahwa Java hanya akan membuat referensi implisit di kelas dalam non-statis. Karena itu, kami harus menjaga hubungan secara manual di mana kami membutuhkannya:

class Wheel { Car car; } class Car { List wheels; }

4. Asosiasi

Asosiasi adalah hubungan terlemah di antara ketiganya. Ini bukan hubungan "memiliki" , tidak ada objek yang merupakan bagian atau anggota dari yang lain.

Asosiasi hanya berarti bahwa objek-objek itu “saling mengenal”. Misalnya, seorang ibu dan anaknya.

4.1. UML

Di UML, kita dapat menandai asosiasi dengan panah:

Jika pengaitannya dua arah, kita dapat menggunakan dua panah, panah dengan panah di kedua ujungnya, atau garis tanpa panah:

We can represent a mother and her child in UML, then:

4.2. Source Code

In Java, we can model association the same way as aggregation:

class Child {} class Mother { List children; }

But wait, how can we tell if a reference means aggregation or association?

Well, we can't. The difference is only logical: whether one of the objects is part of the other or not.

Also, we have to maintain the references manually on both ends as we did with aggregation:

class Child { Mother mother; } class Mother { List children; }

5. UML Sidenote

For the sake of clarity, sometimes we want to define the cardinality of a relationship on a UML diagram. We can do this by writing it to the ends of the arrow:

Note, that it doesn't make sense to write zero as cardinality, because it means there's no relationship. The only exception is when we want to use a range to indicate an optional relationship:

Also note, that since in composition there's precisely one owner we don't indicate it on the diagrams.

6. A Complex Example

Let's see a (little) more complex example!

We'll model a university, which has its departments. Professors work in each department, who also has friends among each other.

Will the departments exist after we close the university? Of course not, therefore it's a composition.

But the professors will still exist (hopefully). We have to decide which is more logical: if we consider professors as parts of the departments or not. Alternatively: are they members of the departments or not? Yes, they are. Hence it's an aggregation. On top of that, a professor can work in multiple departments.

Hubungan antara profesor adalah asosiasi karena tidak masuk akal untuk mengatakan bahwa seorang profesor adalah bagian dari yang lain.

Hasilnya, kita dapat memodelkan contoh ini dengan diagram UML berikut:

Dan kode Java terlihat seperti ini:

class University { List department; } class Department { List professors; } class Professor { List department; List friends; }

Perhatikan, jika kita mengandalkan istilah "has-a", "milik-ke", "anggota-dari", "bagian-dari" , dan seterusnya, kita bisa lebih mudah mengidentifikasi hubungan antara objek kita.

7. Kesimpulan

Dalam artikel ini, kami melihat properti dan representasi komposisi, agregasi, dan asosiasi. Kami juga melihat bagaimana memodelkan hubungan tersebut di UML dan Java.

Seperti biasa, contoh tersedia di GitHub.