gpt4 book ai didi

php - 它是依赖注入(inject)吗?这是一种不好的做法吗?

转载 作者:可可西里 更新时间:2023-10-31 23:02:41 25 4
gpt4 key购买 nike

我有一个小框架,我是这样编码的。我不确定它是否称为依赖注入(inject)。我不知道它是否像设计模式。我也不知道并想知道将 $this 作为参数传递是否是一种不好的做法。

看看这个; (不是一个工作示例,只是将这些代码写入浏览器以进行解释。)

/* This is engine model */
require_once('Database.class.php');
require_once('Image.class.php');
require_once('Misc.class.php');
require_once('BBCode.class.php');

class FrameWork_Engine_Model
{
public $database, $config, $misc, $bbcode, $controller, $image;

function __construct($config)
{
$this->database = new Database($configParams);
$this->image = new Image($this);
$this->misc = new Misc($this);
$this->bbcode = new BBCode($this);
$this->controller = new Controller($this); //here I call Register controller depending on routing, in this case, register controller.
}
...
}

 /* This is register controller */
class Register extends Base_Controller
{
/*I can access anything over Engine Model in my controllers */
$this->engine->database->query(); //I access database model
$this->engine->bbcode->tag('you'); //I access bbcode model
$this->engine->image->sanitizeUploadedFile(); //I access image model

//etc. I can access others models like this.
}

基本上,我的 Controller 可以通过引擎模型访问任何模型。我相信 依赖注入(inject)就是将依赖注入(inject) Controller ? 比如,我的注册 Controller 需要数据库模型、路由模型和模板模型才能工作。这里有它所依赖的一切。我错了吗?

综上所述,我的问题是:

  1. 它是一个有效的依赖注入(inject)示例吗?如果不是,它是什么?它在设计模式中有名称吗?

  2. 如果与依赖注入(inject)无关,需要做哪些改动才能成为DI?

  3. 在新创建的类上传递 $this 参数是一种不好的做法吗?如果是,为什么?

附言。我知道在一个主题中问 3 个问题不是 stackoverflow 喜欢的,但我不想复制粘贴整个文本来问他们。

最佳答案

你快到了。

问题一

不,我不认为它是一个有效的依赖注入(inject)示例。它有点类似于服务定位器(因为您将整个容器注入(inject)到您的服务中并使用它来“定位”依赖的服务)。

问题2

您在依赖注入(inject)和依赖注入(inject)容器之间造成了一点混淆。

首先,依赖注入(inject)意味着在运行时将依赖项推送到对象中,而不是创建/拉取它们。

举个例子:

//hardcoded dependecies
class BadService
{
public function __construct()
{
$this->dep1 = new ConcreteObject1();
$this->dep2 = new ConcreteObject2();
}
}

所以在上面的例子中,BadService使得无法在运行时连接其他依赖项,因为它们已经被硬拉到构造函数本身中。

//service locator pattern
class AlmostGoodService
{
public function __construct(Container $container)
{
$this->dep1 = $container->getADep1();
$this->dep2 = $container->getADep2();
}
}

AlmostGoodService例如,我们已经从前面的示例中删除了硬依赖性,但我们仍然依赖于我们容器的特定实现(这意味着如果不提供该容器的实现,我们的服务将不可重用)。这是与您正在做的事情相匹配的示例。

//dependecy injection    
class GoodService
{
public function __construct($dep1, OptionalInterface $dep2)
{
$this->dep1 = $dep1;
$this->dep2 = $dep2;
}
}

GoodService服务不关心它的具体依赖项的创建,并且可以在运行时轻松地与实现 $dep1 的“协议(protocol)”的任何依赖项“连接”。或 $dep2 的 OptionalInterface (因此得名 Inversion of Control - 依赖注入(inject)背后的基本概念)。

执行此接线的组件称为 dependency injection container .

现在,一个 dependency injection container ,在最简单的形式中,只不过是一个能够在运行时基于某种形式的配置连接你的对象的对象。

我说过你快到了,但是你的实现有一些问题:

  • 布线应该是惰性的(您不希望在您的构造函数中进行所有工作,因为您的应用程序会随着它的增长而显着减慢)
  • 你不应该将整个容器 ( $this ) 作为依赖项传递,因为那样你会回退到较弱的 inversion of control ,即 service locator .您应该将具体依赖项传递给您的服务构造函数

问题3

在某些情况下,您会发现自己想要通过整个 $container作为对服务(即 Controller 或惰性服务工厂)的依赖,但通常最好远离这种做法,因为它会使您的服务更可重用且更易于测试。当您觉得您的服务有太多依赖项时,这是一个好兆头,表明您的服务做了太多事情,现在是拆分它的好时机。

原型(prototype)容器实现

因此,根据我上面的回答,这是一个修改后的(远非完美的)实现:

/* This is the revised engine model */
class FrameWork_Engine_Model
{
function __construct($config)
{
$this->config = $cofig;
}

public function database()
{
require_once('Database.class.php');
return new Database($this->config['configParams']);
}

public function bbcode()
{
require_once('BBCode.class.php');
return new BBCode($this->database());
}

public function image()
{
require_once('Image.class.php');
$this->image = new Image($this->config['extensionName']);
}
....

public function register_controller($shared = true)
{
if ($shared && $this->register_controller) {
return $this->register_controller;
}

return $this->register_controller = new Register_Controller($this->database(), $thus->image(), $this->bbcode());
}
}

现在,要使用您的服务:

$container = new FrameWork_Engine_Model(); 
$container->register_controller()->doSomeAction()

有什么可以改进的?您的容器应该:

  • 提供一种共享服务的方法——即只初始化一次
  • lockable - 提供一种在配置后锁定它的方法
  • 能够与其他容器“合并”——这样您的应用程序将真正模块化
  • 允许optional dependencies
  • 允许scopes
  • 支持tagging services

准备好使用 DI 容器实现

所有这些都附有关于 Dependency Injection 的清晰文档

关于php - 它是依赖注入(inject)吗?这是一种不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15323882/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com