Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are protected constructors considered good practice?

Tags:

oop

php

I'm writing some little helper classes to handle trees. Basically, I have a node and a special root node that represents the tree. I want to keep it generic and simple. This is part of the code:

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

?>

My questions:

  • Is it sensible to force TreeNode instances to be created through TreeNode::addById()?
  • If it's so, would it be good practise to declare TreeNode::__construct() as private/protected?
like image 342
Álvaro González Avatar asked Jun 08 '10 09:06

Álvaro González


People also ask

What happens if constructor is protected?

Protecting a constructor prevents the users from creating the instance of the class, outside the package. During overriding, when a variable or method is protected, it can be overridden to other subclass using either a public or protected modifier only.

Should abstract classes have protected constructors?

An abstract class by definition cannot be instantiated directly. It can only be instantiated by an instance of a derived type. Therefore the only types that should have access to a constructor are its derived types and hence protected makes much more sense than public.


1 Answers

I think that in certain cases it does make sense to control the construction of objects and hide the public constructor.

This is true of your code: it's useful for the Tree class to control how it's child TreeNodes are created and initialized because it needs to control where nodes are added in the tree hierarchy.

Having this control over object construction is especially important if the relationship between the classes is such that the one has information about the other.

For example: if you changed your implementation slightly and allowed the Tree class to manage the node IDs for all nodes in the tree (you might store these in an array within the Tree class). In this case it would be very compelling to have Tree control how TreeNodes are created and initialized and doing this through a method on your Tree class makes perfect sense.

like image 77
dariom Avatar answered Oct 25 '22 23:10

dariom