【问题标题】:Are protected constructors considered good practice?受保护的构造函数被认为是好的做法吗?
【发布时间】:2010-06-08 09:55:25
【问题描述】:

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

<?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() 声明为私有/受保护是否是一种好习惯?

【问题讨论】:

    标签: php oop


    【解决方案1】:

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

    您的代码也是如此:Tree 类控制其子 TreeNodes 的创建和初始化方式非常有用,因为它需要控制在树层次结构中添加节点的位置。

    如果类之间的关系使得一个类拥有另一个类的信息,那么对对象构造的这种控制尤其重要。

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

    【讨论】:

      【解决方案2】:
      • 强制通过TreeNode::addById() 创建TreeNode 实例是否明智?
      • 如果是这样,将TreeNode::__construct() 声明为私有/受保护是否是一种好习惯?

      如果您想通过TreeNode::addById() 强制创建TreeNode唯一 明智的路径是使TreeNode::__construct() 私有或受保护(在这种情况下两者都可以工作,但@ 987654327@ 可能会更好,因为它会强制子类使用::addChildById)。

      至于通过TreeNode::addById()强制创建TreeNode实例是否明智:是的,替代方法是将TreeNode::addById()的逻辑传递给构造函数。虽然在这种情况下可能,但工厂方法通常更通用。

      但是请注意,现在是这样,并且由于在 PHP 中不需要调用父构造函数,可以创建(的子类型) TreeNode 对象通过创建 Tree 对象。您应该考虑将私有构造函数添加到 Tree 以避免实例化。

      更正:虽然在 PHP 中调用父构造函数是正确的,但如果子类中没有指定构造函数,则对父构造函数的隐式调用也是正确的;所以就目前而言,PHP 会尝试调用TreeNode 的父构造函数并在直接实例化Tree 对象时失败。

      【讨论】:

        猜你喜欢
        • 2016-04-07
        • 2013-12-08
        • 1970-01-01
        • 2011-05-26
        • 1970-01-01
        • 2011-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多