Защищенных конструкторов считают хорошей практикой?

Я пишу некоторые небольшие классы помощника для обработки деревьев. В основном у меня есть узел и специальный корневой узел, который представляет дерево. Я хочу сохранить это универсальным и простым. Это - часть кода:

<?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 экземпляры, которые будут созданы через TreeNode::addById()?
  • Если это так, был бы он быть хорошей практикой для объявления TreeNode::__construct() как частный/защищающий?
7
задан Álvaro González 8 June 2010 в 09:55
поделиться

2 ответа

Я думаю, что в некоторых случаях имеет смысл контролировать построение объектов и скрывать публичный конструктор.

Это относится к вашему коду: классу Tree полезно контролировать создание и инициализацию его дочерних TreeNode, потому что ему нужно контролировать, куда добавляются узлы в иерархии дерева.

Наличие такого контроля над созданием объектов особенно важно, если отношения между классами таковы, что один имеет информацию о другом.

Например: если вы немного измените свою реализацию и позволите классу Tree управлять идентификаторами узлов для всех узлов дерева (вы можете хранить их в массиве внутри класса Tree). В этом случае было бы очень убедительно, если бы Tree контролировал, как создаются и инициализируются TreeNodeы, и делать это через метод класса Tree вполне логично.

3
ответ дан 7 December 2019 в 14:29
поделиться
  • Разумно ли принудительно создавать экземпляры TreeNode с помощью TreeNode :: addById () ?
  • Если это так, было бы хорошей практикой объявить TreeNode :: __ construct () как закрытый / защищенный?

Если вы хотите принудительно создать TreeNode через TreeNode :: addById () , только разумный путь - сделать TreeNode :: __ construct () закрытым или защищенным (оба будут работать в этом случае, но закрытый , вероятно, будет лучше, поскольку это заставит подклассы для использования :: addChildById ).

Что касается целесообразности принудительного создания экземпляров TreeNode с помощью TreeNode :: addById () : это так, альтернативой может быть передача TreeNode :: addById () в конструктор. Хотя в этом случае возможно, фабричные методы, как правило, более универсальны.

Однако обратите внимание на , что, как сейчас , и поскольку вызов родительских конструкторов не требуется в PHP, вы можете создать (подтип) TreeNode путем создания объектов Tree . Вам следует подумать о добавлении частного конструктора в Tree , чтобы избежать создания экземпляров.

Исправление: хотя верно, что вызов родительских конструкторов не требуется в PHP, также верно и то, что существует неявный вызов родительского конструктора, если конструктор не указан в подклассе; так что сейчас PHP попытается вызвать родительский конструктор TreeNode и потерпит неудачу при непосредственном создании экземпляра объекта Tree .

1
ответ дан 7 December 2019 в 14:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: