A类是否可以保留B类的依赖关系,因为类A在调用方法后实例化了B类

时间:2013-04-20 15:42:56

标签: php oop dependency-injection

我有一个我调用Dispatcher的类,当运行dispatch()方法时,它会实例化请求的控制器。

我的AbstractController有一个像

这样的构造函数
public function __construct(RequestInterface $request, ResponseInterface $response, ViewFactory $viewFactory, ServiceFactory $serviceFactory)

正如您所看到的,我的控制器有4个依赖项。

在我实例化Dispatcher时,我将ViewFactoryServiceFactory注入其构造函数中,然后当我运行dispatch()方法时,我提供{{1} }}和Request对象作为参数,然后我可以将所有四个依赖项注入我的控制器。

在调用Response方法时提供所有控制器依赖项或在dispatch()的构造函数中提供所有控制器依赖项,然后运行没有参数的Dispatcher方法会更好吗?或者总体上有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

您需要在新控制器实例中注入4个依赖项,2个具有请求/响应生命周期,2个具有更长的生命周期(进程?),然后才能在其上调用某个方法。我会通过创建一个控制器工厂将控制器的创建与调用分开。

控制器工厂将使用仅接收请求并响应对象作为参数的方法来实例化控制器。工厂将意识到两个较长寿命依赖关系的生命周期,可能共享相同的生命周期。然后,工厂的用户可以在返回的(抽象)控制器上自由调用他们想要的任何方法。这比您建议的委托模式更灵活。你当然可以使用委托,但是我可能仍然让Dispatcher只进行调度并将对象创建留给工厂。

当然,这些问题没有正确答案。这一切都取决于很多因素(要求,代码库的大小,项目等)。希望这会有所帮助。祝你好运!

答案 1 :(得分:2)

一些“等等”

以下是我在设计API时使用的经验法则:如果您的类有3个以上的依赖项,那就太多了。

您在构造函数中传递的依赖项应该是实例运行所必需的。在你的情况下,你有一个控制器。控制器的可复制性如下:

  

控制器可以将命令发送到其关联视图,以更改视图的模型显示。它还可以向模型发送命令以更新模型的状态。    来源:wikipedia

控制器应负责创建或呈现视图实例。

关于原始问题:

我不确定Dispatcher实例的作用是什么,但它们本身不应该处理创建逻辑。你最终得到的结果是可能的LoD违规行为和明确的SRP违规行为。

创建逻辑应该与工厂和构建者分开。这种方式还可以让您将Dispatcher实例与控制器构造函数的足迹分离。目前,如果您引入了具有不同依赖关系的不同控制器子类,则还需要更改Dispatcher实现。

至于“如何建造工厂”,您可以找到一个简化的示例here