0

昨天,我在我的一个游乐场项目中实现了一个简单的类作为 IOC 容器(不太像那样),一些专业人士告诉我,在测试代码时会遇到一些问题(太紧张了,无法分享到底是什么)问题 !!)

虽然我自己总是使用 IOC 框架,但我想知道为什么这种方法是不好的?

我什至使用这种方法编写了许多测试(使用模拟框架)并且从未遇到过问题。

我想要你关于这个设计问题的想法:

public class IocContainer{

  private static IocContainer instance;

  private IocContainer(){
  }

  public static IocContainer getInstance()
  {
    if(instance == null){
      instance = new IocContainer();
    }
    return instance;
  }

  public ChatPresenter getChatPresenter(ChatView chatView)
  {
    return new ChatPresenterImpl(chatView, getChatRepo() , getMessagingService());
  }

  private ChatRepo getChatRepo()
  {
    return new ChatRepoImpl(getDbHelper(), getRemoteService());
  }

  private MessagingService getMessagingService()
  {
    return new MessagingServiceImpl()
  }

  private DbHelper getDbHelper()
  {
    return new DbHelperImpl();
  }

  private RemoteService getRemoteService()
  {
    return new RemoteServiceImpl();
  }
}

如您所见,我仅使 getChatPresenter 可访问,并且在我的视图中像下面这样使用它,并且效果很好。

ChatPresenter presenter = IocContainer.getInstance().getChatPresenter(this)

代码在没有任何紧密耦合的情况下处理控制反转(使用接口)。

我想知道这种方法有什么问题吗?(我想从技术角度得到答案,因为我已经知道使用 Ioc 容器库更容易具有更多功能,例如范围等......)

实际上我想知道这种方法将来会带来什么问题和限制?

残忍地杀了我 :D

4

1 回答 1

1

总结评论线索:

您的方法看起来像 Martin Fowler 在此处描述的服务定位器:http ://martinfowler.com/articles/injection.html#InversionOfControl

Martin 描述的内容与您的代码之间有一个主要区别:您的代码直接创建服务的实例,因此更像是工厂而不是注册表。

控制反转的基本思想/目标是通过减少依赖来减少耦合,如果您的容器依赖于服务实现(它需要直接调用构造函数),则不会发生这种情况。因此,您问题中的实现在某种程度上反对该基本思想。

依赖于实现的缺点之一是如果不重新编译容器就无法替换服务。如果您很可能永远不会有不同的实现,那可能不是问题,但如果您可能需要它,服务注册表会更有用。

注册中心通常提供方法来注册服务的实现并根据请求提供服务。交付的内容取决于您的需求,但它可能与找到的第一个实现一样简单,也可能更复杂,例如通过匹配一些参数(有关这方面的一些想法,请查看 CDI 注入点参数和替代方案)。

注册表通常伴随着一些配置注册表的方法,例如通过配置文件或类路径扫描(自动查找存在的插件)。但是,仅编写一些配置注册表的代码也可能就足够了。这完全取决于您需要摆脱哪种耦合(以解决您面临的问题)以及哪种耦合是可以接受的。

于 2018-06-05T20:26:10.677 回答