2009-10-26 45 views

回答

13

几天前回复了类似的问题here, mocking a Singleton。原文是针对C#.Net关于嘲笑单身人士的行为,但仍应适用。

至于单身模式,它本身没有任何问题 - 在许多情况下我们想集中逻辑和数据。但是,单例和静态类之间存在很大差异。将您的单例构建为一个静态类,硬编码将其实现传递给应用程序中的每个消费者 - 这使单元测试变得非常困难!

你想要做的是为你的单例定义一个接口,为你的消费者提供使用方法。反过来,您的消费者通过传递对实现类的引用(通常这是您的应用程序,或者如果您熟悉依赖注入\控制反转,则是容器)。

这是一个框架,无论是谁实例化的消费者,这是负责确保一个和唯一一个实例浮动。从静态类到接口引用真的不是那么大的一个飞跃[如上面的链接所示],你只是失去了一个全局访问实例的便利 - 我知道我知道,全局引用非常诱人,但卢克转身回到黑暗面,你也可以!

一般来说,最佳实践建议避免静态引用,并鼓励对接口进行编程。请记住,仍然可以将这些约束应用于单例模式。按照这些指导原则,你应该没有问题的单元测试你的工作:)

希望这会有所帮助!


单身!=公共静态类,而单==单个实例

1

I'm using the following pattern当我写,我可以模拟一个基于静态的单身人士。代码是Java,但我认为你会得到一个想法。这种方法的主要问题是,你必须放松构造函数来保护包(这种类型击败了一个真正的单例)。 作为一个方面说明 - 代码适用于嘲笑你的“静态”代码而不一定只是调用它的代码

3

缺乏可测试性是经典Singleton模型(返回实例的静态类方法)的主要缺点之一。就我而言,这足以证明可以重新设计任何使用Singletons来使用其他设计的代码。

如果你绝对需要一个单一的实例,那么依赖注入和写入接口,正如johnny g所建议的那样,绝对是要走的路。

0

如果你必须使用一个单身人士(并有理由这样做......但我会尽可能避免它)。我会建议使用IOC容器来管理它。我不知道是否有一个德尔福或不。但是在Java中你可以使用Spring,在.NET中你可以使用Windsor/Castle。一个IOC容器可以容纳Singleton并且可以注册不同的测试实现。

这可能是一个太大的主题进入这个片段以外的地方。

1

我通常只使用Flyton对象或类似值对象的单身。查看IoC容器(如上所述)可能是处理共享对象比单例更好的方法。

考虑到在Smalltalk(其中很多这些模式的起源),真假都是有效的单身:)

+0

...关于Smalltalk中:是的,但真假是_so_可测试:) – mjn 2011-12-01 13:51:49

相关问题