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


Is it ok for class A to hold onto class B's dependencies because class A instantiates class B after invoking a method

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

我的AbstractController有一个类似

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

你可以看到我的控制器有4个依赖项。

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

在调用dispatch()方法时提供所有控制器依赖关系或在Dispatcher的构造函数中全部提供它们,然后运行没有参数的dispatch()方法,或者是否有更好的方法?

你有4个依赖,你想注入一个新的控制器实例,2有一个请求/响应生命周期,2有一个更长的生命周期(进程?),在调用一些方法之前。我将通过创建控制器工厂将控制器的创建与调用分离开来。

控制器工厂将使用一个方法实例化控制器,该方法只接收请求和响应对象作为参数。工厂将知道两个生命周期较长的依赖的生命周期,它们可能共享相同的生命周期。然后,工厂的用户可以自由地在返回的(抽象)控制器上调用他们想要的任何方法。这比您建议的委托模式更灵活。当然,您仍然可以使用委托,但我可能仍然会让Dispatcher只执行分派,而将对象创建留给工厂。

当然,这类问题没有正确答案。这取决于很多因素(需求、代码库的大小、项目等)。希望这能有所帮助。好运!

Some "blah"

这是我在设计API时使用的经验法则:如果你的类有3个以上的依赖项,那么它做得太多了。

在构造函数中传递的依赖项应该是强制的,这样实例才能正常工作。在你的例子中,这里有一个控制器。控制器的职责如下:

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

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

关于原来的问题:

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

创建逻辑应该被隔离到工厂和构建器。这种方法还可以让您将Dispatcher实例与控制器构造函数的占用空间解耦。目前,如果你引入了一个不同的控制器子类,有不同的依赖集,你也需要改变Dispatcher的实现。

关于"如何建厂",你可以在这里找到一个简化的例子。