2016-04-17 7 views
2

Ich versuche, eine fließende Schnittstelle für Baumobjekte zu erstellen.PHP OOP: Fließende Schnittstelle und Baumgraphen

Hier ist ein vereinfachtes Beispiel von dem, was ich im Moment tun:

<?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() 
     ); 
?> 

Ich mag würde den Teil zu reduzieren, wo ich den Baum erstellen. Was ich will, ist, etwas zu tun wie folgt aus:

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

in einer Zeile. Und ohne explizit neue Knoten Instanzen erstellen zu müssen (wie ich es im ersten Code mit new Operatoren getan habe).

Mein Ziel ist es, in der Lage zu sein, einen beliebigen Baum beliebiger Ordnung und seine Knoten in beliebigem Grad zu erstellen, ohne ein Semikolon in den Code einfügen zu müssen.

Antwort

1

Anstatt das Hinzufügen einer Funktion create ich glaube, Sie Ihren Konstruktor und addChild Funktionen ändern sollte konsequent die Eltern/Kind-Beziehung in den Daten herzustellen. Sobald Sie das getan haben, können Sie die addChild-Funktion und den Konstruktor verwenden, um das zu tun, was Sie ohne createChild-Funktion beschrieben haben. Im Moment erlaubt Ihr Konstruktor die Querverknüpfung zwischen verschiedenen Bäumen und Zweigen in den Bäumen, also wird es wahrscheinlich etwas ändern müssen.

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; 
    } 
} 

Mit diesem können Sie ketten neue Objekte in einen Baum:

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

Der Versuch, eine create Funktion zu verwenden ist ein Catch-22 Situation, wo muss man manchmal auch die Eltern und manchmal müssen Sie das Kind. Sie können es mit einem Rückgabeobjekt lösen, das beides enthält, aber ich denke, es ist eine Situation, die besser vermieden wird. Wenn Sie nicht die „(neuer Knoten())“ Syntax gefällt, ist eine statische Funktion könnte der Weg zu gehen:

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

die ein wenig schöner sein könnte, je nach Ihrem Geschmack:

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

Sie können diese Methoden hinzufügen, um so einfach wie möglich zu erstellen.

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

Und verwenden Sie den Code wie folgt.

$root = new node(); 
$root->createManyChild(3)->setFoo();