【问题标题】:Can dependency injection like Typhoon replace multiple singletons?像 Typhoon 这样的依赖注入可以替换多个单例吗?
【发布时间】:2015-02-27 02:29:46
【问题描述】:

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

【问题讨论】:

    标签: objective-c typhoon


    【解决方案1】:

    编辑:Pilgrim 是 Typhoon 的官方 Swift 继任者!!


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

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

    高级类,例如视图控制器,会交给协作者来完成他们的工作。正如你所提到的,你有大约 11 个。现在有两种方法可以将您的班级与协作者联系起来:

    寻找(呼叫)合作者:

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

    上述方法有效,但效果不佳,因为:

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

    替代方案:

    只需通过 init 方法或属性将协作者传入。

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

    这与只是 . . .传递参数?

    您无需硬连接协作者,而是将其作为参数传递。但是现在下一节课是硬连线的!所以你一直这样做,直到你有一个顶级的程序集类,它知道如何从各个部分构建你的视图控制器(和其他类)。如果你这样做:

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

    现在使用台风:

    每个普通应用都会保留一个 Typhoon 实例。它将容纳您的单身人士。

    如果在学习了上述材料后您有更具体的问题,我们很乐意为您提供帮助。

    【讨论】:

    • 嗨,贾斯珀……这就是我一直在寻找的……让我“思考”一下,我可能会回复你。非常感谢。过一个安全的新年! :D 顺便说一句,我喜欢你的网站...非常有创意!
    • 不客气,感谢您对网站的友好评价 :) (实际上,如果您有兴趣,这是一个简单的过程:在线购买一些不错的 HTML5 模板,然后添加内容。对于 AppsQuick.ly 来说,插图是由澳大利亚墨尔本的 Loud&Clear 精心制作的
    • 你为什么在initWitServiceClient 中使用self.serviceClient = serviceClient; 而不是_serviceClient = serviceClient 中的this SO question
    • @Ríomhaire 没有理由,您建议的方式几乎总是更好。编辑答案。
    猜你喜欢
    • 1970-01-01
    • 2013-10-27
    • 2017-07-22
    • 2020-12-20
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    相关资源
    最近更新 更多