Good as you said is an Aggregation meaning they have the same hierarchical level, being one independent of the other, but still related.
To define the best load method you will have to check your usage frequency criteria, I believe that if you constantly use data from this aggregation, it is better to keep it started already in the constructor:
require_once CONTROLLERS.'EnderecoController.php';
class Empresa {
function __construct(){
$this->endereco = new EnderecoController();
}
}
Here the driver of Endereco
is always active along with the company, ie it will always load both files.
Now if you only use in some specific cases, it is better
perform a call loader:
Class App{
function __get($var){
$controller = sprintf('%sController', ucword($var));
if(!isset($this->{$var}) && file_exists(CONTROLLERS."{$controller}.php")){
$this->{$var} = new $controller;
}
if(!isset($this->{$var})){
echo "Variable {$var} not found!";
}
return $this->{$var};
}
}
Class Empresa extends App{
function AddEnderecoEmpresa(){
$this->endereco->save($cdEmpresa);
}
}
Here it will load Endereco
only when you need to use it.