php - 为什么常见的 PHP 框架使用中央核心?

标签 php oop design-patterns frameworks

拥有一个主要的中央核心是为了舒适还是有其他目的?

他们为什么这样做

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

代替

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

然后将所有任务都留给类来处理他们的需求?一旦我们在其中加载不同的类,也不会有一个大对象。

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

这样的

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

这难道不会避免对大核心的需求,同时分散一切吗?或者它只是该死的沉重的精神自慰?

编辑:更正了一个拼写错误。

最佳答案

我是 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 = $kernel->request();

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

简化依赖关系处理

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

提供中央扩展点

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

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

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

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

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

关于类(class)配置

关于您为什么不想这样做的问题:

$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”的所有类的重复功能。为了保持代码干爽,您最终不得不让所有类派生自一个公共(public)基类,这很可能构成继承滥用并加深您的类层次结构。

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

$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();

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

关于php - 为什么常见的 PHP 框架使用中央核心?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4541209/

相关文章:

java - 方法本地内部类成员范围访问

c# - 为什么.NET 中没有 IDateTimeProvider 而 DateTime 有 Now getter?

c# - Acyclic Visitor 相对于 Switch On 类型命令的优势

php - 如何在字符串中查找专有名词?

Mac OS X 上的 PHP 和 MySQL : Access denied for GUI user

php - 摆脱 CodeIgniter URL 中的 Index.php

php - 如何使用php获取存储在Mysql中的多张图片?

python - __init__ 以函数作为参数(使用 NetworkX)

design-patterns - 单例继承

java - 如何在 Java 类中限制对象创建不超过 3 个?