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

时间:2015-10-06 13:18:03

标签: php dependency-injection factory-method

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

我已经在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. 与示例一样,解决方案是向工厂提供实例化依赖关系的责任。
  2. 问题:与不使用依赖注入相同的问题。

    1. 另一个是给工厂构造函数
    2. 提供依赖关系

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

      1. 我在互联网上找到的第三个解决方案是创建一种构建器而不是事件。工厂负责知道要创建哪种对象,构建者将知道如何创建它们。
      2. 问题:构建器DP的角色是否处理依赖关系?我害怕得到与解决方案#1相同的问题。

        我们该怎么做?

1 个答案:

答案 0 :(得分:3)

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

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

这样每个工厂都可以找到工厂。只有它需要的依赖项,链只是简单地编排可用的工厂,因此只需要依赖它们,对它们所依赖的依赖性一无所知。

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

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