2016-04-17 2 views
2

Я пытаюсь создать свободный интерфейс для древовидных объектов.PHP OOP: Свободный интерфейс и древовидные диаграммы

Вот упрощенный пример того, что я в настоящее время сделать:

<?php 
class node { 
    private $childs = array(); 
    private $parent; 

    public function __construct($parent = null) { 
     $this->parent = $parent; 
    } 

    public function addChild($child) { 
     $this->childs[] = $child; 
     return $this; 
    } 

    public function createChild() { 
     return $this->addChild(new node($this)); 
    } 

    public function setFoo() { 
     /* do something */ 
     return $this; 
    } 
} 

$root = new node(); 

$root ->addChild((new node($root)) 
      ->setFoo() 
     )->addChild((new node($root)) 
      ->setFoo() 
     ); 
?> 

Я хотел бы уменьшить ту часть, где я создаю дерево. То, что я хочу сделать что-то вроде этого:

$root->createChild()->setFoo(); 
$root->createChild()->setFoo(); 

в одной строке. И без явного создания новых экземпляров узлов (как это было в первом коде с операторами new).

Моя цель - создать любое дерево любого порядка и его узлы любой степени без необходимости вводить в код ползунки.

ответ

1

Вместо того, чтобы добавить функцию CreateChild Я думаю, вы должны изменить свой конструктор и AddChild функции последовательно установить отношения родителя/ребенка в данных. После того, как вы сделали это, добавьте функцию addChild и конструктор, чтобы использовать то, что вы описали без функции createChild. Прямо сейчас ваш конструктор позволяет перекрестно сшивать между деревьями и ветвями деревья, поэтому в любом случае это может измениться.

class node { 
    private $childs = array(); 
    private $parent; 

    public function __construct(node $parent = null) { 
     if(!is_null($parent)) { 
      $parent->addChild($this); 
     } 
    } 

    public function addChild(node $child) { 
     $this->childs[] = $child; 
     $child->parent = $this; 
     return $this; 
    } 

    public function setFoo() { 
     /* do something */ 
     return $this; 
    } 
} 

При этом вы можете приковать новые объекты в дерево:

$tree = (new node())->addChild(new node()) 
        ->addChild((new node())->setFoo()) 
        ->addChild((new node())->addChild(new node()) 
              ->addChild(new node()) 
              ->setFoo() 
        ); 

Попытка использовать функцию CreateChild улов-22 ситуация, при которой иногда требуется родителю, а иногда вам нужен ребенок. Вы можете решить его с помощью объекта возврата, который содержит оба, но я думаю, что это ситуация, которая лучше избегать. Если вы не любите «(новый узел())» синтаксис, статическая функция может быть путь:

public static function create(node $parent = null) { 
    return new node($parent); 
} 

Какой может быть немного красивее в зависимости от ваших вкусов:

$tree = node::create()->addChild(node::create()) 
         ->addChild(node::create()->setFoo()) 
         ->addChild(node::create()->addChild(new node()) 
               ->addChild(new node()) 
               ->setFoo() 
        ); 
0

Вы можете добавить эти методы, чтобы создать как можно больше детей.

public function createManyChild($nbrOfChild) { 
    for($i = 0; $i < $nbrOfChild; $i++){ 
     $this->addChild(new node($this)); 
    } 
    return $this; 
} 

И используйте код следующим образом.

$root = new node(); 
$root->createManyChild(3)->setFoo(); 
Смежные вопросы