【问题标题】:PHP OOP : Fluent interface and tree graphsPHP OOP:流畅的界面和树形图
【发布时间】:2016-04-17 19:05:27
【问题描述】:

我正在尝试为树对象创建一个流畅的界面

这是我目前所做的一个简化示例:

<?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 运算符所做的那样)。

我的目标是能够创建任意顺序的任何树及其任意程度的节点,而无需在代码中添加分号。

【问题讨论】:

    标签: php oop tree fluent-interface


    【解决方案1】:

    我认为您应该更改构造函数和 addChild 函数以始终如一地建立数据中的父/子关系,而不是添加 createChild 函数。一旦你完成了 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 类情况,有时您需要父项,有时您需要子项。您可以使用包含两者的返回对象来解决它,但我认为最好避免这种情况。如果你不喜欢 "(new node())" 语法,那么静态函数可能是最好的选择:

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

    【讨论】:

      【解决方案2】:

      您可以添加此方法以尽可能创建为子项。

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

      并使用这样的代码。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-16
        • 2010-09-29
        • 2022-08-19
        • 2013-07-30
        相关资源
        最近更新 更多