Паттерн Компоновщик (Composite) на реальном примере

У языка PHP есть мощные инструменты объектно-ориентированного программирования, которые предоставляют широкий выбор вариантов дизайн паттернов. Конечно, наличие большого количества вариантов не всегда позволяет принимать решения проще. Как бы вы спроектировали свое приложение, чтобы его было легко поддерживать и расширять? Как бы вы написали компонент, который могли бы использовать другие члены вашей команды через простой интерфейс? При написании программного обеспечения вы можете самостоятельно решать определенные задачи используя свой опыт, интеллект, удачу, большие дозы напитков с кофеином или любую комбинацию из вышеперечисленных.

Компоновщик (Composite) шаблон состоит из двух частей: абстрактного класса Component и класса Composite, который
наследует абстрактный класс Component. Все Composite объекты происходят от абстрактного класса Component. Любой Component может содержать другие Componentы. Component, содержащий другие Componentы можно рассматривать как Composite. Component без дочерних элементов можно рассматривать как пустой Composite.

В некоторых реализациях Composite проводится разграничения между объектами Composite и объектами Leaf. Объекты Leaf — это Componentы, которые не могут содержать дочерних элементов. Чтобы упростить этот пример, все Componentы могут быть Composite.

Интерфейсы и абстрактные классы похожи, потому что ни один не может использоваться непосредственно для создания экземпляра класса, тоесть объекта. Ключевое отличие состоит в том, что абстрактный класс может иметь некоторые полностью реализованные методы, тогда как интерфейсы имеют только объявления методов.
Используйте абстрактные классы, если вы хотите поддерживать одни и те же методы во всех своих классах наследниках, но у вас есть общие методы, которые могут использоваться классами наследниками. Используйте интерфейсы, когда реализации будут отличаются для большинства или всех методов в подклассах.

Итак приступим к рассмотрению непосредственно кода:

abstract class AbstractInstrument {

    private $name;
    private $category;
    private $instruments = array();

    public function add(AbstractInstrument $instrument) {
        array_push($this->instruments, $instrument);
    }

    public function remove(AbstractInstrument $instrument) {
        array_pop($this->instruments);
    }

    public function hasChildren() {
        return (bool)(count($this->instruments) > 0);
    }

    public function getChild($i) {
        return $this->instruments[$i];
    }

    public function getDescription() {
        echo "- один " . $this->getName();
        if ($this->hasChildren()) {
            echo " который содержит: <br> ";
            foreach($this->instruments as $instrument) {
                echo " <table cellspacing = 5 border = 0> <tr> <td> 
 </td> <td> -";
                $instrument->getDescription();
                echo " </td> </tr> </table> ";
            } }
    }

    public function setName($name) {
        $this->name = $name;
    }
    public function getName() {
        return $this->name;
    }

    public function setCategory($category) {
        $this->category = $category;
    }

    public function getCategory() {
        return $this->category;
    }
}

class Guitar extends AbstractInstrument {
    function __construct($name) {
        parent::setName($name);
        parent::setCategory("гитары");
    }
}

class DrumSet extends AbstractInstrument {
    function __construct($name) {
        parent::setName($name);
        parent::setCategory("ударные");
    }
}

class SnareDrum extends AbstractInstrument {
    function __construct($name) {
        parent::setName($name);
        parent::setCategory("малые барабаны");
    }
}

class BaseDrum extends AbstractInstrument {
    function __construct($name) {
        parent::setName($name);
        parent::setCategory("турецкие барабаны");
    }
}

class Cymbal extends AbstractInstrument {
    function __construct($name) {
        parent::setName($name);
        parent::setCategory("тарелки");
    }
}

$drums = new DrumSet("Tama набор ударников");
$drums->add(new SnareDrum("малый барабан"));
$drums->add(new BaseDrum("большой бас-барабан"));
$cymbals = new Cymbal("набор тарелок zildjian");
$cymbals->add(new Cymbal("маленькая тарелка"));
$cymbals->add(new Cymbal("большая тарелка"));
$drums-> add($cymbals);

$guitar = new Guitar("гитара Gibson");

echo "Список инструментов: <p>";
$drums->getDescription();
$guitar->getDescription();

В результате мы получим иерархическую структуру:

Список инструментов:
- один Tama набор ударников который содержит:
  -- один малый барабан
  -- один большой бас-барабан
  -- один набор тарелок zildjian который содержит:
    -- один маленькая тарелка
    -- один большая тарелка
- один гитара Gibson

Добавить комментарий