为什么常见的PHP框架使用中央Core?

时间:2010-12-27 19:23:46

标签: php oop design-patterns frameworks

是否只是舒适或有其他目的有主要核心?

为什么他们这样做

    $core->A->do();
    $core->B->do();

而不是

    $A->do();
    $B->do();

将所有内容留给课程来处理他们的需求?一旦我们在其中加载不同的类,也不会有一个大对象。

要解决真正的问题:我目前正在使用依赖注入模式为类提供他们需要的东西,但我也问自己,如果所有类都可以访问它们会不会更好资源(例如,配置),无需在每次需要时调用核心。

这个

的排序

MyClass

    $myclass->get_configs();    // get my configs
    $myclass->do_stuff($this->my_configs);    // use them

而不是

MyCore

    $myclass_configs = $this->config->get('configs_for_myclass');    // get configs
    $this->myclass = new MyClass($myclass_configs);    // call the function and give it the configs

难道这不会避免需要大核心,而且还会分散所有内容吗?或者它只是一个疯狂的'沉重的心灵手淫?

编辑:纠正错字。

3 个答案:

答案 0 :(得分:6)

我是Alloy HMVC Framework的所有者和管理者,我选择了一个核心的“内核”对象,原因如下:

它作为工厂很有用

拥有一个用于获取和加载其他对象的核心对象,可以让其他人知道他们可能需要在框架中使用的其他对象的依赖关系。例如,一个典型的用户只知道他们想要使用路由器,但他们不想每次想要使用它时自己构建它。

用户宁愿写:

$router = $kernel->router();

比如:

$router = new SomeFramework\Http\Router(new SomeFramework\Http\Request());

或者:

$router = SomeFramework\Http\Router::getInstance();

实例管理

中心核心对象还可以确保在没有必要时多次实例化对象。对于Request,Response,Router,Session等对象,通常不需要有多个实例。

所以调用检索这样的Request实例:

$request = $kernel->request();

将在第一次调用时自动创建并实例化一个新的Request对象,然后使用一个简单的类级别缓存来存储该实例,以便在后续调用中使用,以减少开销。

简化依赖性处理

中心核心或内核对象也可用于简化框架内部的依赖性处理(用作服务定位器)。您无需事先了解对象之间的依赖关系,而只需传递核心对象并知道可以直接从中检索所需的任何内容。这在框架中特别有用,因为您永远不知道用户在其控制器中想要做什么。你只需要为它们提供一个核心对象,它们就可以从中获取所需的任何东西。值得一提的是,这种服务定位器风格的方法确实附带了一个已知的警告,即使用它的所有对象在服务定位器本身上创建依赖关系。缺点是您可能想要或可能不想接受的权衡,但它极大地简化了用户级代码,因此它是我选择制作的代码。

提供中央扩展点

存在一个中心对象并在任何地方传递(并且在任何Controller中可用)的好处之一是它提供了一个自然的公共扩展点。 Alloy允许用户在通过__call魔术函数代理的内核对象上添加自己的方法:

$kernel->addMethod('bark', function() { echo 'Woof!'; });

允许您在内核可用的应用程序中的任何位置使用它:

$kernel->bark(); // echos 'Woof!'

这为插件提供自定义功能或在内核上创建自己的工厂方法以创建辅助对象等提供了一种很好的方法,而无需创建一个全新的插件架构来支持它。

关于班级配置

关于你为何不想这样做的问题:

$myclass->get_configs();    // get my configs
$myclass->do_stuff($this->my_configs);    // use them

而不是:

$myclass_configs = $this->config->get('configs_for_myclass');    // get configs
$this->myclass = new MyClass($myclass_configs);    // call the function and give it the config

原因有两个:

(1)“get_config”所有类的重复功能。为了保持代码DRY,您最终必须使所有类派生自一个公共基类,这很可能构成继承滥用并加深您的类层次结构。

(2)当你对这个对象进行多次方法调用时,每次传入configs都会很乏味和丑陋,即:

$myclass->do_stuff($this->my_configs);
$myclass->do_other_stuff($this->my_configs);
$myclass->do_more_stuff($this->my_configs);

使用配置实例化对象要好得多:

$myclass = new MyClass($myclass_configs);
$myclass->do_stuff();
$myclass->do_other_stuff();
$myclass->do_more_stuff();

由于该配置必须来自某个地方,并且您不一定希望您的用户必须全部输入或在其他地方硬编码,您只需将它从公共核心对象中拉出来,因为它已经加载了整个应用程序中使用的通用配置文件。

答案 1 :(得分:3)

他们可能会这样做以减少全局命名空间中的事物数量,因此不会有数百个你不能使用的类名,而只有一个。

答案 2 :(得分:1)

我认为部分原因是因为如果你执行$ core-> A而不是$ A,那么$ core-> A只有在你请求时才可以延迟加载。