3

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

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

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

4

3 回答 3

2

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

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

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

于 2011-02-03T15:33:58.670 回答
0

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

#define DBM [DropboxModel sharedInstance]

<...>
[DBM uploadFile:aFile];
于 2011-02-03T20:16:27.273 回答
0

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

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

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

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

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

于 2011-02-03T22:21:51.863 回答