Joubert的blog post刚露出我的眼睛。我已经用Java和其他语言处理了很多设计模式。但Objective-C是一种相当独特的语言。
假设我们在项目中与第三方API(如Dropbox或Facebook)进行交谈。到目前为止,我一直在做的是将与第三方API有关的所有内容组合到一个单例类中。所以我可以从视图控制器的任何地方访问该类。我可以举个例子:[[DropboxModel sharedInstance] uploadFile:aFile]
然而,正如博客文章指出的那样,这种效率并不高,导致意大利面条代码和糟糕的单元测试。那么,设计系统的最佳方式是什么,使其模块化且易于使用?
答案 0 :(得分:2)
我会质疑单身人士导致意大利面条代码并且效率低下的想法。然而,单元测试问题是合法的,单例确实减少了模块化,因为它们实际上只是花哨的全局变量。
我喜欢Joubert关于将单例实例从app委托注入控制器的想法(这本身就是一个单身人士,咳嗽)。我认为同样的方法对你有用。
在我可能希望在单元测试中使用不同的存根对象的情况下,我通常会做的是定义一个协议来表示API并使我的“真正的”API对象符合它以及我的存根API对象。我在单元测试中使用存根,在应用程序中使用真实对象。
答案 1 :(得分:0)
这并不能解决与单例相关的任何架构问题,但为了便于阅读和打字,您可以随时在DropboxModel头文件中定义一个宏,例如:
#define DBM [DropboxModel sharedInstance]
<...>
[DBM uploadFile:aFile];
答案 2 :(得分:0)
我通常会创建一个抽象层。这将一个简单的接口包装到您使用的库调用上,同时让您有机会介绍您需要的任何状态(例如变量)。
然后,您可以只公开您需要和使用的内容,并添加您自己的状态,检查,并方便地从一个地方处理库的所有问题。可能由于以下几个原因引入“问题” - 它可能是跨版本的线程,资源,状态或不期望的行为更改。
大多数图书馆并不仅仅是通过单身人士使用。在这种情况下,创建接口是最好的(主观的) - 当然,要注意抽象层背后的约束。从这个意义上说,您只需创建基于对象的接口,这些接口按大小/任务/目的/功能划分 - 就像您在编写自己的类时通常所做的那样。
如果你不需要整个库,那么我认为包装你需要的东西来最小化依赖关系(在大型项目中越来越重要)。
如果您在整个地方使用库,那么您可能也更喜欢使用没有抽象层的调用。