Шаблон проектирования "Компоновщик"
18 мая 2020Относится к структурным шаблонам.
Используется для компоновки объектов в древовидные структуры для представления иерархий, позволяя одинаково обращаться к отдельным объектам и к группе объектов.
Пример на PHP
Пусть имеется интерфейс Animal и 2 класса животных - Parrot и Crocodile, реализующих интерфейс Animal:
interface Animal
{
public function __construct(string $name);
public function getName(): string;
public function setWeight(int $weight);
public function getWeight(): int;
}
class Parrot implements Animal
{
protected int $weight;
protected string $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function getName(): string
{
return $this->name;
}
public function setWeight(int $weight)
{
$this->weight = $weight;
}
public function getWeight(): int
{
return $this->weight;
}
}
class Crocodile implements Animal
{
protected int $weight;
protected string $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function getName(): string
{
return $this->name;
}
public function setWeight(int $weight)
{
$this->weight = $weight;
}
public function getWeight(): int
{
return $this->weight;
}
}
Создадим класс Zoo, состоящий из разных животных и подсчитаем общий вес животных:
class Zoo
{
protected array $animals = [];
public function addAnimal(Animal $animal)
{
$this->animals[] = $animal;
}
public function getTotalWeight(): int
{
$weight = 0;
foreach ($this->animals as $animal) {
$weight += $animal->getWeight();
}
return $weight;
}
}
// Создаем животных
$gena = new Crocodile("Gennadiy", 120);
$kesha = new Parrot("Kesha", 0.5);
// Добавляем животных в зоопарк
$zoo = new Zoo();
$zoo->addAnimal($gena);
$zoo->addAnimal($kesha);
echo "Total weight: " . $zoo->getTotalWeight(); // 120.5
Пример на Go
package main
type IAnimal interface {
GetName() string
GetWeight() int
}
type Parrot struct {
name string
weight int
}
func (p *Parrot) GetName() string {
return p.name
}
func (p *Parrot) GetWeight() int {
return p.weight
}
type Crocodile struct {
name string
weight int
}
func (p *Crocodile) GetName() string {
return p.name
}
func (p *Crocodile) GetWeight() int {
return p.weight
}
type Zoo struct {
animals []IAnimal
}
func (z *Zoo) AddAnimal(animal IAnimal) {
z.animals = append(z.animals, animal)
}
func (z *Zoo) GetTotalWeight() int {
totalWeight := 0
for _, v := range z.animals {
totalWeight += v.GetWeight()
}
return totalWeight
}
func main() {
gena := Crocodile{
name: "Gena",
weight: 120,
}
kesha := Parrot{
name: "Kesha",
weight: 1,
}
zoo := Zoo{}
zoo.AddAnimal(&gena)
zoo.AddAnimal(&kesha)
zoo.GetTotalWeight() // 120.5
}
Источники:
http://designpatternsphp.readthedocs.io/ru/latest/Structural/Composite/README.html
https://habrahabr.ru/company/mailru/blog/325492/