设计:传递类实例还是使用单例?

时间:2010-11-04 13:52:43

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

我的应用程序项目包含几个服务于所有类型的帮助程序类 不同目的(例如时间/日期/计算,数据库访问,......)。 启动这些类是很昂贵的,因为它们包含一些 需要从数据库填写或需要填写的属性 每次创建新实例时重新计算。为了避免表现 问题我倾向于在应用程序委托中启动这些类中的每一个 并将这些从viewController传递给viewController。

这对我有用了一段时间,但我现在发现的更多 复杂的应用程序正在遇到更多我遇到的问题。 大多数问题与课程纠缠在循环引用中有关。 我想知道如何正确解决这个问题,我想到了 将每个辅助类转换为单例,并使用单例而不是 传递一个类实例。但是因为一些辅助类依赖于 彼此我会有单身人士称其他单身人士,我似乎无法 弄清楚这是否会最终导致其他问题。 有人对此提出任何建议吗?

5 个答案:

答案 0 :(得分:4)

单身人士的问题在于,他们更难以模拟和单元测试您的应用程序。你应该解耦你的依赖;如果你以某种方式需要一个单例(这应该是非常非常罕见的),那么考虑让单例实现一个可以模拟用于测试目的的接口。

答案 1 :(得分:1)

每当我想要使用单身人士时,我会重新阅读Global Variables are Bad并考虑是否真的值得提出这个(略微)释义的问题清单:

  • 方法和变量的非本地化
  • 无访问控制或约束检查
  • 隐式耦合
  • 并发问题
  • 命名空间污染
  • 内存分配问题
  • 非常复杂的测试

答案 2 :(得分:1)

单身人士基本上是全局变量,创建一个全局变量只是为了避免传递事物是个坏主意。然后,通常正确的做法是简单地将对象从一个类传递到另一个类。诀窍在于确定可以传递的最小数据量以最小化耦合。这是精心设计的课程很重要的地方。例如,您很少需要传递NSManagedObjectContext,因为您可以从任何NSManagedObject获取它。

现在,让我来解决您的昂贵创建对象的具体情况。您可以尝试pooling those objects而不是每次需要时都创建它们。数据库访问就是一个很好的例子。您不是每次要求分配数据库连接,而是从缓存中获取一个。当然,当缓存为空时,您需要分配一个缓存。而且,出于内存原因,您应该愿意并且能够在系统要求时清空缓存。

创建对象很昂贵对用户来说无关紧要。这是一个实现细节,但它是你可以设计的。你必须要小心,因为只有那些没有可变状态的对象才能以这种方式处理,所以如果你想走这条路,你可能不得不重新考虑你的类的设计。

答案 3 :(得分:1)

为什么不让您的应用为昂贵的创建实例委派工厂?每次视图控制器都需要帮助程序类的实例时,它会向appDelegate询问它。

答案 4 :(得分:0)

就个人而言,我通常使用单身人士 在我看来,它使代码更清晰......

我确信类实例是唯一的。 我用它来单点访问资源

编辑:似乎我错了!
那灵活的实施怎么样?

static Singleton *sharedSingleton = nil;

+ (Singleton*)sharedManager
{
  if (sharedSingleton == nil) {
    sharedSingleton = [[super alloc] init];
  }
  return sharedSingleton;
}