一个简单的IOC容器类有什么问题?

时间:2018-06-05 08:21:48

标签: java architecture inversion-of-control ioc-container testability

去年我在我的一个游乐场项目中实现了一个简单的类作为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

1 个答案:

答案 0 :(得分:1)

总结评论记录:

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

Martin描述的代码与您的代码之间存在重大差异:您的代码直接创建服务实例,因此更像是工厂而不是注册表。

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

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

注册表通常提供注册服务实现并根据请求提供服务的方法。哪个交付取决于您的需求,但它可以像第一个实现一样简单或更复杂,例如通过匹配一些参数(对于某些想法,看看CDI注入点参数和替代品)。

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