Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/237.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 这种设计模式有没有一个名称(将您自己传递到您自己的依赖项中),这种技术的陷阱是什么?_Php_Oop_Design Patterns_Delegation - Fatal编程技术网

Php 这种设计模式有没有一个名称(将您自己传递到您自己的依赖项中),这种技术的陷阱是什么?

Php 这种设计模式有没有一个名称(将您自己传递到您自己的依赖项中),这种技术的陷阱是什么?,php,oop,design-patterns,delegation,Php,Oop,Design Patterns,Delegation,我不盲目地遵循设计模式(我们真的只需要理解对象通信),但我也不想忽视它们 设计模式是否有一个名称(类似于或某种双重分派策略模式之类的东西),但不必重写每个方法和委派,只需将一个引用($this)传递给自己到依赖项中即可?这是程序员工具箱中的合理解决方案吗 需要一个实际的例子吗?当然……继续 假设您使用的是DI容器,可能有一些控制器(MVC)方法如下: 图1: // Phew! Four dependencies injected here: public function index(Quer

我不盲目地遵循设计模式(我们真的只需要理解对象通信),但我也不想忽视它们

设计模式是否有一个名称(类似于或某种双重分派策略模式之类的东西),但不必重写每个方法和委派,只需将一个引用($this)传递给自己到依赖项中即可?这是程序员工具箱中的合理解决方案吗

需要一个实际的例子吗?当然……继续


假设您使用的是DI容器,可能有一些控制器(MVC)方法如下:

图1:

// Phew! Four dependencies injected here:
public function index(QueryManagerInterface $queryManager, BlogQueryInterface $blogQuery, RenderQueryPDFInterface $queryPDFRenderer, RequestInterface $request) {

    // Do some "managing" of a query, then render it into a PDF

    $queryManager->setQuery($query);
    $queryManager->addInput($request->input());
    $queryPDFRenderer->setQuery($query);
    $output = $queryPDFRenderer->render();

    return $output;
}
// Nice! Just two dependencies!
public function index(BlogQueryInterface $blogQuery, RequestInterface $request) {

    $blogQuery->getQueryManager()->addInput($request->input());
    $output = $blogQuery->getPDFRenderer()->render();

    return $output;
}
现在,设想控制器方法如下所示:

图2:

// Phew! Four dependencies injected here:
public function index(QueryManagerInterface $queryManager, BlogQueryInterface $blogQuery, RenderQueryPDFInterface $queryPDFRenderer, RequestInterface $request) {

    // Do some "managing" of a query, then render it into a PDF

    $queryManager->setQuery($query);
    $queryManager->addInput($request->input());
    $queryPDFRenderer->setQuery($query);
    $output = $queryPDFRenderer->render();

    return $output;
}
// Nice! Just two dependencies!
public function index(BlogQueryInterface $blogQuery, RequestInterface $request) {

    $blogQuery->getQueryManager()->addInput($request->input());
    $output = $blogQuery->getPDFRenderer()->render();

    return $output;
}
我是怎么做到的?所有这些类中的所有代码都是相同的,只是我更新了$blogQuery类:

Class BlogQuery Implements BlogQueryInterface, QueryManageableInterface, PDFRenderableInterface {

   public function __construct(QueryManagerInterface $manager, $PDFRendererInterface $pdfRenderer){

      // Here I pass a reference of this own class into its dependencies
      $this->manager = $manager->setQuery($this);
      $this->pdfRenderer = $pdfRenderer->setQuery($this);
   }

   public function getQueryManager() { return $this->manager; }
   public function getPDFrenderer() { return $this->pdfRenderer; }

   ...

}
图2的优点是:

  • 减少对控制器方法的依赖
  • 更少的代码行
  • 组合重于继承(更松散耦合?)
  • 不需要像使用委托模式时那样“键入一堆重复的方法”
  • 更容易理解。注入BlogQuery和请求似乎捕获了主上下文。(主观)

我在图2中使用了什么模式?这种方法的缺点是什么?这种方法被认为是良好的oop实践吗?

在我看来,这就像是,
\uuu构造
使
查询管理器界面
PDFrenderInterface
成为
博客查询
的访问者

我不想太多地涉及编程模式的利弊,因为在大多数情况下,它们都是有利的。但是,访问者模式的一个非常客观的结果是,与其他选项相比,它往往在文件/类之间有更多的跳跃,这使得读者更难将其加载到他们的大脑中。最终,“良好的OOP实践”归结为经验、判断,并可能重写三次


我想指出的是,您并没有真正减少
索引
函数的依赖性。是的,它需要更少的参数,但它仍然知道
querymanagerface
renderQueryPDInterface
的行为。如果这些接口发生更改(例如,重命名
addInput
render
),则
索引中的代码也必须更改。在测试
索引时,仍然需要设置或模拟这两个对象,才能通过测试。除非您可以将该行为隐藏在
BlogQueryInterface
RequestInterface
(另请参见)中,
index
在这两种方法中具有完全相同的依赖关系。

我也不会盲目地遵循设计模式,但当其他人可以轻松理解您所做的工作时,它确实会有所帮助。我认为,如果大家都了解并使用类似的方法,那么它在工作流方面会更有帮助。如果这真的有名字,我会很感兴趣的,问得好!我认为第二个例子比第一个更糟糕,BlogQuery不应该了解PDFrenderer。我觉得控制器有几个依赖项并不奇怪。