我有一个应用程序,在许多应用程序的方法和类中使用了大约11个不同的Singleton实例。它已经失控了,我想用依赖注入(inject)(例如Typhoon)替换所有它们。但是,我找不到任何文档,示例或提及如何使用依赖注入(inject)(包括台风)替换单例的信息。例如,我是否使用多个台风实例,将每个单例替换为一个台风实例?

最佳答案

编辑: Pilgrim是台风的官方Swift继承者!

台风创作者在这里。是的,依赖注入(inject)的用途之一是提供单例的好处而没有缺点。但是您不一定需要一个库来应用依赖项注入(inject)模式并替换您的单例。实际上,它通过先如何在不使用框架的情况下查看如何实现来帮助理解该模式:
好莱坞原则:请勿致电给我们,我们会给您打电话
诸如 View Controller 之类的高级类服从于协作者来完成他们的工作。正如您所提到的,其中大约有11个。现在有两种方法可以将您的类(class)与协作者联系起来:
寻找(调用)合作者:

initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle
{
    self = [super initWithNibName:nibname bundle:bundle];
    if (self) {
        _serviceClient = [MyServiceClient sharedInstance];
    }
}
上面的方法行得通,但是不好,因为:
  • 如果要提供替代的实现,则必须去更改使用它的每个类。
  • 这使编写干净的单元或集成测试变得困难。您必须查看类的内部(玻璃盒测试),而不是专注于外部接口(interface)协定(黑盒测试)。
  • 它提供了过于紧密的耦合,这导致了较差的内聚性。

  • 替代方案:
    只需通过init方法或属性将协作者传递进来。
    initWitServiceClient:(id<ServiceClient>)serviceClient
    {
        self = [super initWithNibName:@"MyNib" bundle:[NSBundle mainBundle];
        if (self) {
            _serviceClient = serviceClient;
        }
    }
    
    这与just有什么不同。 。 。传递论点?
    您不必将协作者硬接线,而是将其作为参数传递。但是现在,下一个类的工作就很辛苦了!因此,您将继续执行此操作,直到拥有顶级组装类为止,该类知道如何从各个零件中构建 View Controller (和其他类)。如果您这样做:
  • 每个单例的所有引用都指向一个地方。因此,使用兼容的实现替换您的单例仅需要一行代码。同样,您已经封装了此类的配置。
  • 它易于为您的类编写单元测试和集成测试。在后一种情况下,您可以将一个组件修补为另一个组件。这可以克服集成式测试的两个缺点。第一个原因是很难将系统置于测试方案所需的状态,第二个原因是它们可能会产生有害的副作用。同时,纯单元测试也得到了简化,因为它现在很容易看到依赖关系契约,并为它们传递了模拟或 stub 。
  • 类清楚地记录了他们的“接缝”,以及为执行任务将委派给他们的重要协作者。这导致“高内聚性”。

  • 现在正在使用台风:
    每个普通应用程序将保留一个Typhoon实例。它将容纳您的单例。
  • 声明装配that defines your singletons。给他们singleton scope
  • 使用plist integration在您的应用程序中启动台风。台风的ample app shows如何执行此操作。
  • 定义一个程序集,该程序集定义并注入(inject)您的 View Controller 。 Typhoon sample app显示了如何执行此操作。或者使用auto-wiring macros。如果您使用 Storyboard ,这些功能将非常好用。

  • 如果在研究了上述 Material 之后,您还有一个更具体的问题,我们将很乐意为您提供帮助。

    09-25 16:44