Can dependency injection like Typhoon replace multiple singletons?

Spo*_*ude 5 objective-c typhoon

I have an app that has about 11 different Singleton instances used throughout the many app's methods and classes; it's getting out of hand, and I want to replace all of them with dependency injection, like Typhoon. However, I am unable to find any doc, sample or mention of how to replace the singletons with dependency injection, including Typhoon. For instance, do I use multiple instances of Typhoon, replacing each singleton with an instance of Typhoon?

Jas*_*ues 9

台风创造者在这里.是的,依赖注入的一个用途是提供单身人士的好处而没有缺点.但是,您不一定需要库来应用依赖注入模式并替换您的单例.事实上,通过首先看看如何在没有框架的情况下实现它来理解模式是有帮助的:

好莱坞原则:不要打电话给我们,我们会打电话给你

像视图控制器这样的高级别课程会让合作者去做他们的工作.正如你所提到的,你有大约11个.现在有两种方法可以将您的班级与合作者联系起来:

寻找(召集)合作者:

initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle 
{
    self = [super initWithNibName:nibname bundle:bundle];
    if (self) {
        _serviceClient = [MyServiceClient sharedInstance];
    }
} 
Run Code Online (Sandbox Code Playgroud)

以上方式有效,但不好,因为:

  • 如果要提供替代实现,则必须更改使用它的每个类.
  • 它使编写干净的单元或集成测试变得困难.您必须查看类的内部(玻璃盒测试),而不是关注外部接口合同(黑盒测试).
  • 它提供过紧的耦合,导致内聚力差.

替代方案:

只需通过init方法或属性传递协作者.

initWitServiceClient:(id<ServiceClient>)serviceClient
{
    self = [super initWithNibName:@"MyNib" bundle:[NSBundle mainBundle]; 
    if (self) {
        _serviceClient = serviceClient;
    }
} 
Run Code Online (Sandbox Code Playgroud)

这与众不同...传递参数?

而不是为协作者进行硬连接,而是将其作为参数传递.但现在下一堂课很难接线!所以你一直这样做,直到你有一个顶级汇编类,它知道如何从各个部分构建你的视图控制器(和其他类).如果你这样做:

  • 每个单例的所有引用都指向一个地方.因此,用兼容的实现替换一个单例只需要一行代码更改.同样,您已封装此类的配置.
  • 它易于为您的类编写单元和集成测试.在后一种情况下,您可以将一个组件修补为另一个组件.这可以克服集成式测试的两个缺点.第一个是难以将系统置于测试场景所需的状态,第二个是它们可能具有不必要的副作用.同时,纯单元测试也得到了简化,因为它现在很容易看到依赖合同并传递这些模拟或存根.
  • 课程清楚地记录了他们的"接缝"以及他们将委派给他们执行任务的重要合作者.这导致"高内聚力".

现在使用Typhoon:

每个普通应用程序你将有一个保留的Typhoon实例.它会抓住你的单身人士.

如果在研究了上述材料后您有更具体的问题,我们将非常乐意为您提供帮助.