或者最好使用其他设计模式?
答案 0 :(得分:13)
几天前回复了类似的问题here, mocking a Singleton。
是关于嘲笑单身人士的行为的原始帖子是针对C#.Net的。关于单例模式,它本身没有任何问题 - 在许多情况下我们希望集中逻辑和数据。但是,单例和静态类之间存在很大差异。将单例构建为静态类硬编码,实现应用程序中的每个使用者 - 这使得单元测试非常困难!
您要做的是为您的单身人士定义一个界面,公开让消费者使用的方法。您的消费者反过来传递对实现类的引用,只要实例化它们[通常这是您的应用程序,或者如果您熟悉依赖注入\控制反转,则为容器]。
正是这个框架,无论是谁实例化消费者,都负责确保一个且只有一个实例浮动。从静态类到接口引用实际上并没有那么大的飞跃[如上面的链接所示],你只是失去了全局可访问实例的便利性 - 我知道,全球引用非常诱人,但是Luke背弃了黑暗面,你也可以!
一般来说,最佳实践建议避免使用静态引用,并鼓励对接口进行编程。请记住,仍然可以应用具有这些约束的单例模式。遵循这些指导原则,单元测试您的工作应该没有问题:)
希望这有帮助!
singleton!=公共静态类,而不是 singleton == single instance
答案 1 :(得分:3)
缺乏可测试性是经典Singleton模型(返回实例的静态类方法)的主要缺陷之一。就我而言,这足以重新设计任何使用Singletons来使用其他设计的代码。
如果你绝对需要一个单一的实例,那么依赖注入和写入接口,就像johnny g所建议的那样,绝对是可行的方法。
答案 2 :(得分:1)
I'm using the following pattern当我写一个基于静态的单例时,我可以嘲笑。代码是Java,但我想你会得到一个想法。这种方法的主要问题是你必须放松构造函数以打包保护(哪种类型会破坏真正的单例)。 作为旁注 - 该代码适用于模拟“静态”代码的能力,而不一定只是简单地调用它
答案 3 :(得分:1)
我通常只使用Singletons作为Flyweight对象或类似的值对象。查看IoC容器(如上所述)可能是处理共享对象而不是单例的更好方法。
考虑在Smalltalk(很多这些模式的起源),真假都是有效的单身人士:)
答案 4 :(得分:0)
如果你必须使用单身人士(并且有理由这样做......但如果可能的话,我会尽量避免使用它)。我建议使用IOC容器来管理它。我不确定是否有一个Delphi。但是在Java中你可以使用Spring,在.NET中你可以使用Windsor / Castle。 IOC容器可以保存到Singleton上,并且可以注册不同的实现以进行测试。
除了这个片段之外,进入这里的主题可能太大了。