Reputation: 8101
Currently I have a Controller
class with 20+ various methods.
I have identified an area with 4 methods, which I would like to extract into its own separate class. (that is my overriding goal to have methods that belong in to specific area like a "menu", in a "menu" class). So I want to put those 4 methods into their own class, but keep 16+ methods in the original "global" class.
In my case, extracting the Menu subcomponent I could do this:
Create a class MenuController
, extend main Controller
, and then have variables $menu
and $main
respectively (because I still need access to functionality of the 20+ methods. Call one that is needed, i.e. $menu->menuMethod();
What I want to do however is to call $main->menu->showMenu()
I do not see how to do this I keep running into trouble.
What I have ..
class Controller
{
function __construct()
{
//dependencies
$this->repository = new Repository();
$this->renderer = new PhpRenderer();
//subcontroller
$this->menu = new MenuController();
}
}
class MenuController extends Controller
{
function __construct()
{
//to pick up all the dependencies in Controller
parent::__construct();
}
function showMenu()
{
echo "menu";
}
}
Problem
When Controller
initializes, it calls MenuController
, and then MenuController
calls parent()
, which calls Controller
's initialization method, and this repeats in an infinite loop.
What I want
I want something like this:
$main = new Controller();
$main->menu->showMenu();
Or
$main = new Controller(MenuController());
$main->menu->showMenu();
Or
/*
* or I could instantiate two separately
* in which case I'd want some mechanism to *share* dependencies
* because those dependencies are expensive
*/
$main = new Controller();
$menu = new MenuController()
$main->showMenu();
where MenuController inherits its dependencies from Controller, without me having to explicitly redefine all of them for both classes, while having syntax like above.
Can this be done or am I chasing the impossible?
Upvotes: 1
Views: 143
Reputation: 455
I think I get what you are trying to accomplish. You would want to define your classes like this.
class Controller
{
function __construct()
{
//dependencies
$this->repository = new Repository();
$this->renderer = new PhpRenderer();
}
private function createMenu()
{
$this->menu = new MenuController();
}
}
class MenuController extends Controller
{
function __construct()
{
//to pick up all the dependencies in Controller
parent::__construct();
}
function showMenu()
{
echo "menu";
}
//This will prevent this class from calling the parent method to create itself. You would still have a null reference to $this->menu on this class tho
private final function createMenu()
{
throw new Exception('I can\'t do this');
}
}
Now this works as you wanted.
$main = new Controller();
$main->createMenu();
$main->menu->showMenu();
Upvotes: 2