Вы не должны определять родителя или ссылку на него, потому что вы можете оказаться в цикле ссылок, что не плохо в коде, но в дизайне и может в конечном итоге сделать ваш код невозможным для понимания, когда вещипойти не так.
Что касается функции addNode
, вы, кажется, находитесь на правильном пути,
public function addNode(Node $new)
{
//no need for getters and setters from inside the class
$new->level = $this->level + 1;
$this->nodes[] = $new;
return $this;
}
Я не уверен, что вы пытаетесь сделать с left
иright
хотя.но я предполагаю, что верхний родительский путь расположен слева, а нижний дочерний - справа.В этом случае я бы просто дифференцировал его от уровня.
Я бы также не использовал приватный и использовал защищенный, в основном я сделал это здесь, так что я могу пройти весь путь без использования добытчиков исеттеры, чтобы сделать код более компактным, но сделать это так, как вам хочется:
class Node
{
/**
* @var static
*/
protected $parent;
/**
* @var static[]
*/
protected $nodes = [];
/**
* @var int
*/
protected $level = 1;
/**
* @var int
*/
protected $left = 0;
/**
* @var int
*/
protected $right = 0;
public function addNode(Node $new)
{
$new->level = $this->level + 1;
$new->parent = $this;
$new->left = $new->level - 1;
if (empty($this->nodes)) {
$this->right = 1;
}
$curr = $this;
while (null !== $curr->parent) {
//walking up to the current parent and telling it there is a new level added
$curr->parent->right++;
//setting the current level 1 up
$curr = $curr->parent;
}
$this->nodes[] = $new;
return $this;
}
}
И так как я возвращаю $this
, я могу связать все подряд или вложить вызовы addNode, например
$country = new Node();
$state = new Node();
$city = new Node();
$country->addNode($state->addNode($city));