如何创建共享主控制器的许多依赖关系的子控制器类?

时间:2016-10-13 19:43:58

标签: php design-patterns dependencies

目前我有一个Controller课程,有20多种不同的方法。

我已经确定了一个有4种方法的区域,我想将它们提取到自己独立的类中。 (这是我的首要目标,即在"菜单"类中使用属​​于特定区域的方法,如"菜单")。所以我想把这4个方法放到他们自己的类中,但是在原来的#34; global"中保留16个以上的方法。类。

在我的例子中,提取Menu子组件我可以这样做:

创建一个类MenuController,扩展主Controller,然后分别拥有变量$menu$main(因为我仍然需要访问20多种方法的功能。拨打一个所需的电话,即$menu->menuMethod();

我想要做的是致电$main->menu->showMenu() 我不知道如何做到这一点我一直遇到麻烦。

我有什么......

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";
    }
}

问题

Controller初始化时,它会调用MenuController,然后调用MenuController调用parent(),这会调用Controller的初始化方法,这样在无限循环中重复。

我想要什么

我想要这样的事情:

$main = new Controller();
$main->menu->showMenu();

或者

$main = new Controller(MenuController());
$main->menu->showMenu();

或者

/* 
 * 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();

其中MenuController从Controller继承其依赖项,而不必为两个类显式重新定义它们,同时具有上述语法。

这可以做到还是我在追逐不可能的事情?

1 个答案:

答案 0 :(得分:2)

我想我得到了你想要完成的事情。您可能希望像这样定义类。

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');
    }
}

现在这可以按照您的意愿运作。

$main = new Controller();
$main->createMenu();
$main->menu->showMenu();