What are some specific legitimate uses for singletons?
Possible Duplicate:
On Design Patterns: When to use the Singleton?
这个问题不在于一般来说,单件物品是否"被认为是有害的"。我只是想从你的经验中知道,在哪些特定的情况下,单身汉似乎工作得很好。
编辑:请,如果你想讨论一下单子的恰当性和/或邪恶性,一般来说,有一个现成的问题:1379751831
哎呀!我刚刚发现我的问题已经在这里被问到了:关于设计模式:何时使用单例?
我们基本上将它们用于两个方面:日志记录和配置。两者都假定应用程序有一个中心配置和一个中心日志文件,并不总是有效的,但在我们的大多数代码中是有效的。我们有时也会将它们用于某些工厂类或缓存类,以确保不会复制密钥元数据。
正在展开我的评论…
这个问题措词不好,单件似乎在许多情况下都能很好地解决。它应该是"在某些特定的情况下,单子不暴露它们的负属性?"简而言之,"什么时候全局变量是好的"?
全局变量是全局变量。
一旦你使用
{
X* x = X::getInstance();
...
}
您点的意大利面已被接受,而不是
单子繁殖,并且喜欢互相依赖。
单子抑制可测试性。
单实例属性仅在生产代码中半有用。您可能根本无法测试
你可以猜到,我对全局变量什么时候好的答案是什么?是"永远"。你的是什么?
生成一个随机数序列-随机生成器应该是唯一的,而不是为每次使用而实例化。人们可能希望将其作为线程级的单例实现;但是,在这种情况下,整个进程的单例仍然是合适的。
- 当您的域指定您正在建模的对象只有一个唯一的实例时
我仍然认为应该避免独生子女(至少在Java中)。
有两个不同的问题需要考虑:概念和执行单例模式的机制。
单例的概念有很多用途,比如日志记录、配置,更不用说当您正在工作的域实际上有一些东西,其中只有一个实例,并且您希望对其进行建模。也就是说,一个公司只有一个费用处理办公室,把费用表格发给一个无效的办公室是错误的,办公室实际上是一个单独的办公室。单例概念有许多合法的用途。
然而,问题通常是由这种机制引起的。在Java中,我们不能通过声明构造器EDCOX1(10)来构造一个对象,问题是,我们还必须通过具体类提供对实例的全局访问点。这将应用程序中的所有内容与具体的类结合在一起,具体的类在运行时是不能更改的,或者在单元测试中是模拟的。这种机制被认为是邪恶的,特别是在可测试性方面。
如果单子的概念可以从可怜的机制中分离出来,它们就不会那么邪恶了。我能想到的一个例子是,在guice中可用的
登录中。
查找本地化字符串资源,如
Strings.get("CONFIRM_DELETE") 。
这两者都不是应该在对象的公共接口中公开的细节,所以在这里使用单例是有意义的。
系统有一个单独的设备/硬件,必须有一个中央控制点才能正确使用。
除了日志记录(正如大多数其他人已经提到的那样),我还使用了单例来反转控制(IOC)容器。依赖项在应用程序开始时注册一次,并且可以使用singleton方法在应用程序期间的任何时间点解析依赖项。
我尽量不依赖单例,但是我更喜欢去耦而不是不使用单例。因此,我经常将singleton与原型模式结合使用,这允许在库加载时注册原型(全局对象构造)。
我正在编写一个由多个库组成的服务器。有许多"公共"库,然后每个服务一个库。"主"库的任务是查看接收到的消息,并根据密钥调用正确的服务…这使用一个简单的
使用一个单例映射允许我拥有完全分离的代码。没有一个库依赖于我的服务库,没有一行代码在我的服务库之外负责注册它的服务。实际上,我可以通过在编译时修改我的"link"命令来决定嵌入哪些服务:如果我没有链接到库,那么它的服务就不会嵌入。
我真的觉得这很有用…对于配置和类似的配置,我更喜欢使用单模式:即所有实例共享相同数据(从而包装一个真正的单模式)的普通类。这样可以更容易地进行迁移,以防客户不知道他们使用的是单人卧底。
主服务器接收来自客户机的请求,并将这些请求传递给一个下级进程。从属进程可以使用单例来与主服务器通信。
我只是努力工作,在我正在做的这个项目中摆脱了单身汉。它们有气味,但有时很难避免。
我的情况是,我有一个API,它构建了用于处理管理功能(如安全性、配置等)的单例对象。该API使用EntityFramework,还拉入了插件(使用MEF)。因为这些类的构造并不总是由我的代码(尤其是EF实体)执行的,所以不可能总是将它们优雅地注入到biz对象中。所以我使用了单例,它可以在项目主体的范围内的任何地方访问。
当程序的一部分需要一个实现特定接口(多态性方面)的对象时,您永远不需要该对象的多个实例。否则静态方法就可以了。
它们适用于您希望将其视为唯一资源的项目。
作为Web系统中的一个例子,您可能希望只对所服务的每个页面使用一个数据库连接——在本例中,使用singleton模式是有意义的。(尽管您必须知道数据库访问对象是单例的,这不太理想,但如果有明确的文档记录,则可以接受,等等。)