2010-06-08 21 views
7

Escribo algunas pequeñas clases de ayuda para manejar árboles. Básicamente, tengo un nodo y un nodo raíz especial que representa el árbol. Quiero mantenerlo genérico y simple. Esto es parte del código:¿Los constructores protegidos se consideran buenas prácticas?

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

?> 

Mis preguntas:

  • ¿Es sensato para forzar TreeNode casos que se crean a través de TreeNode::addById()?
  • Si es así, ¿sería una buena práctica declarar TreeNode::__construct() como privado/protegido?

Respuesta

3

Creo que en ciertos casos tiene sentido controlar la construcción de objetos y ocultar el constructor público.

Esto es cierto de su código: es útil para la clase Tree para controlar cómo se crea TreeNode s hijo y se inicializa porque necesita controlar dónde se agregan los nodos en la jerarquía de árbol.

Tener este control sobre la construcción del objeto es especialmente importante si la relación entre las clases es tal que una tiene información sobre la otra.

Por ejemplo: si modificó ligeramente su implementación y permitió que la clase Tree administrara las ID de nodo para todos los nodos en el árbol (puede almacenarlos en una matriz dentro de la clase Tree). En este caso sería muy convincente tener Tree controlar cómo se crean e inicializan TreeNode s y hacer esto a través de un método en su clase Tree tiene mucho sentido.

1
  • ¿Es sensato para forzar TreeNode casos que se creará a través TreeNode::addById()?
  • Si es así, ¿sería una buena práctica declarar TreeNode::__construct() como privado/protegido?

Si desea forzar TreeNode que ser creado a través TreeNode::addById(), la única vía razonable es hacer que el TreeNode::__construct() privada o protegida (tanto funcionaría en este caso, pero private probablemente sería mejor, ya que obligaría a las subclases a usar ::addChildById).

En cuanto a si es sensato forzar TreeNode instancias que se crearán a través de TreeNode::addById(): es decir, la alternativa sería transferir la lógica de TreeNode::addById() al constructor. Si bien es posible en este caso, los métodos de fábrica son generalmente más versátiles.

Nótese, sin embargo, que ya que ahora es, y desde llamar a los constructores padres no se requiere en PHP, que puede crear (un subtipo de) TreeNode objetos mediante la creación de objetos Tree. Debería considerar agregar un constructor privado al Tree para evitar la creación de instancias.

Corrección: aunque es cierto que no se requiere llamar a los constructores padre en PHP, también es cierto que hay una llamada implícita al constructor padre si no se especifica ningún constructor en la subclase; así como ahora, PHP intentará llamar al constructor padre de TreeNode y fallará cuando se ejecute directamente un objeto Tree.

Cuestiones relacionadas