在这个网站上有很多关于为什么应该避免单身人士的讨论,但有没有单身人士有意义并且是最佳选择的情况?
我认为单例是最佳选择的示例是在实现Identity Map时需要跟踪已从映射层中的数据库加载的所有模型。在这种情况下,重要的是地图实际上是全局的,以便所有客户端代码使用相同的地图实例,并且它们都访问相同的加载模型列表。最简单的解决方案似乎是将类实现为单例(或静态方法)。这是最好的方法还是有另一种方式?
是否有其他情况可以使用单身或者总是不好?
答案 0 :(得分:1)
请参阅this thread。
答案 1 :(得分:1)
单身人士的确有其用途。我总结一下它们的用处:
“单身人士应该用来表示其对象,根据基本设计或要求,最多只能有一个实例;并且有与该对象相关的数据或资源会产生可测量的成本。”这就是我的意思。
1)在有很多东西的情况下你不应该使用Singleton,但我们只碰巧对它感兴趣。如果系统中可能存在两个,则明确地实例化一个。
2)Singleton的许多用法可以用具有所有静态方法和数据的类替换。如果你能做到这一点而没有性能损失,那就去做吧。
3)如果设置对象有明显的成本,您应该考虑使用Singleton:例如,如果它是需要初始化的物理资源,或者它依赖于需要初始化的某个查找表。如果是这种情况,使用Singleton,您可以将初始化成本推迟到第一次使用对象,而静态类通常会在应用程序启动时初始化。如果从未使用该对象,则永远不会支付初始化成本。
答案 2 :(得分:1)
当您需要仅一个实例并且想要通过设计强制执行时,应使用单身人士。由于它引起的全局副作用,不应该被使用。
在你的情况下,我认为这是有道理的,因为你只想限制一个类的实例。
答案 3 :(得分:0)
在不允许静态接口成员的语言中使用单例(和类似的) - 例如在.NET中。通过提供单例,您可以拥有一个可以将接口作为实例提供的实例。所以在.NET中,例子可能是:
Comparer<T>.Default
- 提供用于排序IComparer<T>
T
实施
EqualityComparer<T>.Default
- 为散列/相等测试提供IEqualityComparer<T>
实施T
这是一种手段 - 结束;这不是我们想要做的,只是一个合理的“如何”。
就“身份地图”示例而言,我个人宁愿将其保留在实例上,并使实例可用于我的所有代码。除了其他任何东西,如果您可以在测试之间丢弃地图,或者可以灵活地(稍后)同时拥有多个身份地图,它可以帮助测试。
答案 4 :(得分:0)
考虑您希望将应用程序中的不同事件记录到单个文件的情况。在这种情况下,单例类Log将很有用。由于应用程序的不同部分将访问Log类的相同实例。
答案 5 :(得分:0)
单身人士确实有自己的用途。他们也有滥用权力,有很多理由不喜欢他们或为什么他们让测试变得困难。
这是对Singleton模式的一个小小的辩护。
有时,程序需要代表真正独特的东西或与之互动。一个例子是物理资源。例如,你不能有一个'stdout'。以及OS过程的表示(例如J2ME的Midlet)。
Singletons就像在使用类/接口来提供封装一样,并且这些优点对于裸体全局变量是值得的。
答案 6 :(得分:0)
当您使用网络编程时,单身人士才有意义:您通常只需要每个请求一个页面输出类的实例,以及一个用户对象。数据库是不同的 - 实现权限分离是想要多个数据库对象的一个很好的理由。
答案 7 :(得分:0)
我的个人指南是,如果您之后可以实例化一个类的一个对象,则永远不要将类硬编码为单例。这使得单例非常罕见,并且在应用程序代码中通常是不必要的。使用像Spring这样的DI框架时尤其如此。
单身人士确实在框架中用作“入口点”,但规则是将它们用作“根单例”(在依赖关系层次结构的开头)并让其余代码依赖于该单例尽量少。