【问题标题】:What is the correct system design when dealing with third party API?处理第三方 API 时正确的系统设计是什么?
【发布时间】:2011-02-03 14:32:29
【问题描述】:

Joubert 的 blog post 让我大开眼界。我处理过很多 Java 和其他语言的设计模式。但 Objective-C 是一种相当独特的语言。

假设在一个项目中,我们使用第三方 API,例如 Dropbox 或 Facebook。到目前为止,我一直在做的是将与第三方 API 相关的所有内容组合到一个单例类中。所以我可以从我的视图控制器中的任何地方访问这个类。例如,我可以去:[[DropboxModel sharedInstance] uploadFile:aFile]

但是,正如博客文章所指出的,这效率不高,并导致意大利面条式代码和糟糕的单元测试。那么,设计系统以使其模块化且易于使用的最佳方式是什么?

【问题讨论】:

    标签: objective-c cocoa-touch design-patterns ios cocoa-design-patterns


    【解决方案1】:

    我不同意单例会导致意大利面条式代码并且效率低下的想法。但是,单元测试问题是合理的,单例确实会降低模块化,因为它们实际上只是花哨的全局变量。

    我喜欢 Joubert 将单例实例从应用委托(它本身就是一个单例,咳咳)注入控制器的想法。我认为同样的方法对你有用。

    在这些我可能想在单元测试中使用不同存根对象的情况下,我通常会定义一个协议来表示 API,并使我的“真实”API 对象符合它以及我的存根 API 对象。我在单元测试中使用存根,在应用程序中使用真实对象。

    【讨论】:

    • 通过存根对象,你的意思是我应该创建一个虚拟的 Dropbox 帐户,并将密码硬编码到我的单元测试中吗?我不确定这是否是一种好方法......但也许你是对的。
    • 我不知道硬编码密码是个好主意 :-) 我的意思是广义的“存根对象”。它根本不需要真正连接到投递箱,它可以伪造响应。
    • 这就是我的意思,我永远不想硬编码我的密码,但我还能如何确保我得到响应并正确处理来自 Dropbox 的响应? Twitter API 也是如此。有什么方法可以自动化吗?
    【解决方案2】:

    并不是说这真的解决了与单例相关的任何架构问题,但为了可读性和可打字性,您始终可以在 DropboxModel 头文件中定义一个宏,例如:

    #define DBM [DropboxModel sharedInstance]
    
    <...>
    [DBM uploadFile:aFile];
    

    【讨论】:

      【解决方案3】:

      我通常会创建一个抽象层。这将一个简单的接口包装到您使用的库调用中,同时让您有机会引入您需要的任何状态(例如变量)。

      然后您可以只公开您需要和使用的内容,并添加您自己的状态、检查并从一个位置方便地处理库的所有问题。引入“问题”的原因可能有多种 - 可能是线程、资源、状态或跨版本的不良行为变化。

      大多数库并不意味着只能通过单例来使用。在这种情况下,最好(主观地)像往常一样创建接口——当然,要注意抽象层背后的约束。从这个意义上说,您只需创建基于对象的接口,这些接口按大小/任务/用途/功能划分——所有这些都是您在编写自己的类时通常会做的。

      如果你不需要到处都是这个库,那么我认为包装你需要的东西来最小化依赖关系也很好(在大型项目中越来越重要)。

      如果您到处使用该库,那么您可能更喜欢使用没有抽象层的调用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多