使用工厂方法 DP 处理依赖注入

Handle dependency injection with factory method DP

我们必须实现一个能够创建多个复杂对象的工厂。 我们应该如何使用依赖注入来处理它?

我已经在 Whosebug(和其他地方)中阅读了很多关于它的主题,尤其是 Mark Seemann 的主题,但无法做出任何决定,因此需要您的意见。

例如:

<?php
class EventFactory
{
    public function createEvent($type)
    {
        switch ($type) {
            case 'upload':
                return new UploadEvent(new FtpUploader(), new Mailer());
            case 'download':
                return new DownloadEvent(new FtpDownloader(), new Mailer());
            case 'save':
                return new SaveEvent(new EventDbModel());
            case 'load':
                return new LoadEvent(new EventDbModel());
            case 'notify':
                return new NotifyEvent(new HttpRequester());
        }
    }
}

我找到了一些解决方案,但不知道该选择哪个。

  1. 一个解决方案就像示例中一样,将实例化依赖项的责任交给工厂。

问题:与未使用依赖注入相同。

  1. 另一种是给工厂构造函数依赖

问题:构造函数中的参数会很多,列表会长大

  1. 我也在互联网上找到的第三个解决方案是创建某种构建器而不是事件。工厂有责任知道要创建哪种对象,而构建者将知道如何创建它们。

问题:builder DP的作用是处理依赖吗?我害怕遇到与解决方案 #1 相同的问题。

我们该怎么办?

就我个人而言,我会选择选项 2。当您想要配置建筑物但对客户端隐藏实现时,通常会使用构建器。当您只需要传递参数时,工厂通常会更好。

如果您担心参数的数量,那么您可以将参数对象传递给工厂,或者生成单一责任工厂,每个工厂都知道他们创建的东西的类型以及如何创建它,然后 assemble 将它们划分为责任链,询问每个人是否可以创建请求的类型,如果不能则将其传递,或者甚至只是一个简单的列表 'single type factory' 个实例。

这样每个 'factory' 只有它需要的依赖项,而链只是简单地编排可用的工厂,因此只需要对它们的依赖项,对它们有什么依赖项一无所知。

不使用责任链更简单。像这样的一些解决方案:

public class EventFactory
{
    IEnumerable<ISingleTypeEventFactory> factories

    public EventFactory(IEnumerable<ISingleTypeEventFactory> factories)
    {
         this.factories = factories;
    }


    public Event CreateEvent($type)
    {
         foreach(factory in factories)
         {
              if (factory.CanHandleType($type))
              {
                   return factory.CreateEvent($type);
              }
         }
    }
}