Komposisi adalah ketika suatu object A
mengandung object B
dan object A
juga bertanggung jawab untuk menciptakan object B
.
Hubungan komposisi
Kami memiliki kelas A yang akan digunakan oleh kelas B.
final class A
{
}
Ada beberapa pilihan bagaimana komposisi dapat terlihat.
Komposisi inisialisasi langsung:
final class B
{
private $a = new A();
}
Komposisi inisialisasi konstruktor
final class B
{
private $a;
public function __construct()
{
$this->a = new A();
}
}
Komposisi inisialisasi malas
final class B
{
private $a = null;
public function useA()
{
if ($this->a === null) {
$this->a = new A();
}
/* Use $this->a */
}
}
Anda melihat ini menciptakan hubungan yang erat antara kelas A
dan B
. Kelas B
tidak bisa ada tanpa A
. Ini adalah pelanggaran besar prinsip injeksi ketergantungan , yang mengatakan:
Ketergantungan adalah objek yang dapat digunakan (layanan). Suntikan adalah perpindahan ketergantungan ke objek dependen (klien) yang akan menggunakannya. Layanan ini menjadi bagian dari keadaan klien. Melewati layanan ke klien, alih-alih membiarkan klien membangun atau menemukan layanan, adalah persyaratan mendasar dari pola tersebut.
Komposisi terkadang masuk akal, seperti memanggil new DateTime
dalam php ataunew std::vector<int>
dalam C ++. Tetapi lebih sering daripada tidak, itu adalah peringatan, bahwa desain kode Anda salah.
Dalam kasus, di mana class A
objek khusus akan digunakan untuk caching, itu class B
akan selalu di-cache menggunakan implementasi class A
, dan Anda tidak akan memiliki kontrol untuk mengubahnya secara dinamis, yang buruk.
Juga, jika Anda menggunakan komposisi inisialisasi malas , berarti Anda akan memiliki sebuah karya object B
, yang disebut useA()
metode dan penciptaan object A
akan gagal, Andaobject B
tiba-tiba tidak berguna.
Agregasi, di sisi lain, adalah cara hubungan, yang mengikuti prinsip DI . object B
perlu digunakan object A
, maka Anda harus melewati contoh yang sudah dibuat object A
untuk object B
, dan harus pembuatanobject A
gagal, tidak ada yang akan berlalu di tempat pertama.
Singkatnya, Agregasi adalah representasi UML untuk prinsip injeksi ketergantungan , baik injeksi konstruktor, injeksi setter, atau injeksi properti publik.
Ini semua adalah Agregasi
Injeksi konstruktor yang paling kencang ( object B
tidak bisa ada tanpa object A
).
final class B
{
private $a;
public function __construct(A $a)
{
$this->a = $a;
}
}
Looser (Anda mungkin atau mungkin tidak menggunakan object A
di dalam object B
, tetapi jika Anda melakukannya, Anda mungkin harus mengaturnya terlebih dahulu).
Melalui setter:
final class B
{
private $a;
public function setA(A $a)
{
$this->a = $a;
}
}
Melalui properti publik:
final class B
{
public $a;
}
Sebenarnya tidak ada cara yang bagus untuk membenarkan penggunaan Agregasi atas Komposisi, jika semua yang Anda gunakan adalah implementasi konkret dari kelas, tetapi begitu Anda mulai menyuntikkan antarmuka atau dalam kasus kelas abstrak C ++, tiba-tiba Agregasi akan menjadi satu-satunya cara untuk memenuhi kontrak Anda.