受保护的建筑商是否被认为是良好的做法

我正在写一些小帮手来处理树木。 基本上,我有一个节点和一个代表树的特殊根节点。 我想保持它的通用性和简单性。 这是代码的一部分:

<?php

class Tree extends TreeNode{
    public function addById($node_id, $parent_id, $generic_content){
        if( $parent = $this->findNodeById($parent_id) ){
            $parent->addChildById($node_id, $generic_content);
        }
    }
}

class TreeNode{
    public function __construct($node_id, $parent_id, $generic_content){
        // ...
    }

    protected function addChildById($node_id, $generic_content){
        $this->children[] = new TreeNode($this->node_id, $node_id, $generic_content);
    }
}

$Categories = new Tree;
$Categories->addById(1, NULL, $foo);
$Categories->addById(2, NULL, $bar);
$Categories->addById(3, 1, $gee);

?>

我的问题:

  • 强制通过TreeNode::addById()创建TreeNode实例是否明智?
  • 如果是这样,将TreeNode::__construct()声明为private / protected是否是好习惯?

  • 我认为在某些情况下,控制对象的构建并隐藏公共构造函数确实有意义。

    这是你的代码的真实情况:对于Tree类来说,控制它的子TreeNode是如何被创建和初始化是很有用的,因为它需要控制树层次结构中添加节点的位置。

    如果这些类之间的关系是一个关于另一个的信息,那么对对象构造进行这种控制就显得尤为重要。

    例如:如果稍微更改了实现,并允许Tree类管理Tree中所有节点的节点ID(可将这些节点存储在Tree类中的数组中)。 在这种情况下,让Tree控制如何创建和初始化TreeNode并通过Tree类中的方法进行初始化非常有吸引力,这非常有意义。


  • 强制通过TreeNode::addById()创建TreeNode实例是否明智?
  • 如果是这样,将TreeNode::__construct()声明为private / protected是否是好习惯?
  • 如果你想强制TreeNode通过TreeNode::addById()创建, 唯一明智的方法是使TreeNode::__construct() private或protected(两者都适用于这种情况,但private可能会更好,因为它将强制子类使用::addChildById )。

    至于是否强制通过TreeNode::addById()来创建TreeNode实例是TreeNode::addById() :它是,另一种方法是将TreeNode::addById()的逻辑传递给构造函数。 尽管在这种情况下可能,工厂方法通常更通用。

    但是,请注意,现在,由于调用父构造函数在PHP中不是必需的,因此可以通过创建Tree对象来创建TreeNode对象的一个​​子类型。 您应该考虑为Tree添加一个私有构造函数以避免实例化。

    更正:尽管在PHP中不需要调用父构造函数是确实的,但如果在子类中没有指定构造函数,那么也有对父构造函数的隐式调用; 就像现在一样,PHP会尝试调用TreeNode的父构造函数,并在直接实例化Tree对象时失败。

    链接地址: http://www.djcxy.com/p/46113.html

    上一篇: Are protected constructors considered good practice?

    下一篇: AJAX call not working in jQGrid