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


Handle dependency injection with factory method DP

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

我已经在stackoverflow(和其他地方)上读了很多关于它的话题,特别是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. 一个解决方案是,就像在这个例子中,给工厂的责任来实例化依赖。

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

另一种方法是给工厂构造器提供依赖项

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

  • 我在互联网上发现的第三个解决方案是创建一种构建器而不是事件。工厂有责任知道要创建哪种对象,而构建器也知道如何创建它们。
  • 问题:构建器DP的角色是处理依赖关系吗?我担心会遇到和解决方案1一样的问题。

    我们该怎么办?

    我个人倾向于选择2。当您想要配置构建但对客户端隐藏实现时,通常使用构建器。当你只需要传递参数时,工厂通常是更好的选择。

    如果你担心参数的数量,那么你可以传递一个参数对象给工厂,或者创建单个责任工厂,每个工厂都知道他们创建的东西的类型和如何创建它,然后将它们组装成一个责任链,询问每个工厂是否可以创建请求的类型,如果不能传递它,甚至只是一个简单的列表"单一类型工厂"实例。

    这样,每个"工厂"只有它需要的依赖项,而链只是编排可用的工厂,所以只需要依赖它们,而不知道它们有什么依赖项。

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

    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);
                  }
             }
        }
    }