PHP OOP: Kompozice a agregace (Composition and Aggregation) [11]
Kompozice (composition, složení) je v OOP způsob, jak kombinovat základní objekty či data do složitějších (ve složené objekty, v celky, vztahy mezi objekty). Tyto složené objekty je pak možné používat stejně jako základní objekty. Zásadní je, že kompozitní objekty nemají nezávislou existenci viz níže příklad kompozice = objekt Person nemůže existovat bez objektu AddressBook.
Jinak řečeno - složené objekty jsou součástí jen jediného objektu a existence mimo tento kompozit není možná.
Kompozice vs agregace
Oproti kompozici agregace znamená, že jde o volnou vazbu mezi objekty = objekty mají nezávislou existenci viz níže příklad agregace = objekt Person může existovat bez objektu AddressBook.
Jinak řečeno - objekt má jiné objekty jen jako části, ty mohou být součástí více objektů a existence mimo agregát je možná.
Kompozice vs dědičnost
Jak jsme si již uvedli v jedné lekci - dědičnost se používá k rozšiřování existujících tříd (nová třída vzniklá na základě staré) = vhodné když nová třída má stejné vlastnosti jako již existující třída a zároveň od ní chceme něco navíc. Jedná se o vztah is a (A is a B).
Kompozice se zase používá, když objekt obsahuje více jiných objektů. Jedná se o vztah has a (A has a B).
Obecně se má spíše dát přednost kompozici před dědičností.
Příklad kompozice v OOP
https://github.com/hydroxid/php_examples/blob/main/3686_composition_and_aggregation/composition.php
class Person
{
private $name;
private $address;
public function __construct(string $name, string $address)
{
$this->name = $name;
$this->address = $address;
}
public function getName()
{
return $this->name;
}
public function getAddress()
{
return $this->address;
}
}
class AddressBook {
private $persons = [];
private $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
// difference from aggregation example
public function addPerson($name, $address)
{
// difference from aggregation example
$this->persons[] = new Person($name, $address);
}
public function getPersons()
{
return $this->persons;
}
}
$addressBook = new AddressBook('My address book (with composition)');
// difference from aggregation example
$addressBook->addPerson('Tom', 'Street 7, Town 34237');
$addressBook->addPerson('John', 'Street 3, Small Town 43564');
$addressBook->addPerson('Doe', 'Street 88, Big City 33664');
echo $addressBook->getName() . PHP_EOL;
foreach ($addressBook->getPersons() as $person) {
echo $person->getName() . PHP_EOL;
echo $person->getAddress() . PHP_EOL;
}
Příklad agregace v OOP
https://github.com/hydroxid/php_examples/blob/main/3686_composition_and_aggregation/aggregation.php
class Person
{
private $name;
private $address;
public function __construct(string $name, string $address)
{
$this->name = $name;
$this->address = $address;
}
public function getName()
{
return $this->name;
}
public function getAddress()
{
return $this->address;
}
}
class AddressBook {
private $persons = [];
private $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
// difference from composition example
public function addPerson($person)
{
// difference from composition example
$this->persons[] = $person;
}
public function getPersons()
{
return $this->persons;
}
}
$addressBook = new AddressBook('My address book (with aggregation)');
// difference from composition example
$addressBook->addPerson(new Person('Tom', 'Street 7, Town 34237'));
$addressBook->addPerson(new Person('John', 'Street 3, Small Town 43564'));
$addressBook->addPerson(new Person('Doe', 'Street 88, Big City 33664'));
echo $addressBook->getName() . PHP_EOL;
foreach ($addressBook->getPersons() as $person) {
echo $person->getName() . PHP_EOL;
echo $person->getAddress() . PHP_EOL;
}