Kompozisyon ne zaman bir object A
içerir object B
ve object A
aynı zamanda oluşturmaktan da sorumludur object B
.
Kompozisyon ilişkisi
B sınıfı tarafından kullanılacak A sınıfı var.
final class A
{
}
Kompozisyonun nasıl göründüğü gibi çok sayıda seçenek vardır.
Doğrudan başlatma bileşimi:
final class B
{
private $a = new A();
}
Oluşturucu başlatma bileşimi
final class B
{
private $a;
public function __construct()
{
$this->a = new A();
}
}
Tembel başlatma kompozisyonu
final class B
{
private $a = null;
public function useA()
{
if ($this->a === null) {
$this->a = new A();
}
/* Use $this->a */
}
}
Bunun sınıflar A
ve arasında sıkı bir ilişki yarattığını görüyorsunuz B
. Sınıf, B
basitçe var olamaz A
. Bu çok büyük bir ihlalidir bağımlılık enjeksiyon prensibine diyor:
Bağımlılık kullanılabilecek bir nesnedir (bir servis). Bir enjeksiyon, bir bağımlılığın, onu kullanacak olan bağımlı bir nesneye (bir müşteriye) geçmesidir. Servis müşterinin durumunun bir parçası. Bir müşterinin hizmeti oluşturmasına veya bulmasına izin vermek yerine, servisi müşteriye geçirmek, modelin temel gereksinimidir.
Kompozisyon bazen new DateTime
php veya new std::vector<int>
C ++ ile arama gibi anlamlıdır . Ancak çoğu zaman, kod tasarımınızın yanlış olduğu bir uyarıdır.
class A
Önbelleğe almak için kullanılan özel bir nesnenin olacağı bir durumda, class B
uygulamanın kullanılmasıyla her zaman önbelleklenir class A
ve dinamik olarak değiştirmeyi kontrol edemezsiniz; bu kötüdür.
Ayrıca, tembel başlatma kompozisyonunu kullandıysanız , yani bir çalışmanızın object B
, useA()
yöntem denilen ve yaratmanın object A
başarısız olacağı anlamına gelir object B
, aniden işe yaramazsınız.
Öte yandan, bir araya getirme, DI ilkesini izleyen bir ilişki biçimidir . object B
kullanımına ihtiyaç object A
, o zaman zaten oluşturulmuş örneğini geçmelidir object A
için object B
ve oluşturulması gerektiğini object A
güzünde şey ilk etapta devredilecek.
Kısacası, Toplama bağımlılık enjeksiyon prensibi için UML temsilidir , yapıcı enjeksiyon, ayarlayıcı enjeksiyon veya genel özellikli enjeksiyon.
Bunların hepsi Toplamalar
En sıkı yapıcı enjeksiyonu ( object B
onsuz yapılamaz object A
).
final class B
{
private $a;
public function __construct(A $a)
{
$this->a = $a;
}
}
Daha gevşek ( object A
içinde kullanabilir veya kullanmıyor olabilirsiniz object B
, ancak yaparsanız önce onu ayarlamanız gerekir).
Setter ile:
final class B
{
private $a;
public function setA(A $a)
{
$this->a = $a;
}
}
Genel mülk aracılığıyla:
final class B
{
public $a;
}
Kompozisyon üzerinde Toplama kullanımını haklılaştırmanın gerçekten harika bir yolu yoktur, eğer kullanıyorsanız hepsi sınıfların somut uygulamaları ise, ancak bir kez arayüzleri enjekte etmeye başladığınızda veya C ++ özet sınıfları durumunda, birdenbire toplanmanın tek yolu bu olacaktır. sözleşmesini yerine getirmek.