On design patterns: When should I use the singleton?
class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
}
答案 0 :(得分:16)
简单。单身人员做了什么?
所以当你需要两者时,你会使用单身人士。
这很少见。 全球通常都说不好。我们倾向于尽可能避免使用它们。 并且围绕“如果存在多个实例,这是一个错误”的假设构建应用程序是危险的,因为您通常会发现假设不成立。也许您希望能够在本地创建多个实例,以用于缓存目的。也许事实证明,您需要多个数据库,多个日志,或者线程性能要求您为每个线程提供自己的实例。
在任何情况下,您都不需要强制执行“只有一个实例可能存在”的假设。如果您只需要一个实例,只需创建一个实例。但是保持构造函数是公开可见的,这样就可以创建更多的实例如果它是必要的。
换句话说,单身人士提供的两个功能实际上都是负面的。一般来说,我们希望我们的数据不会全局可见,而且我们希望无缘无故地带走灵活性。
如果您确实需要单例提供的功能之一,请实现该功能,而不需要另一个功能。如果您需要全局可访问的内容,请将其设置为全局。不是单身人士。如果你确实需要强制只存在一个实例(我想不出你想要的任何合理的情况),那么实现它,而不是全局可见性。
我所见过的唯一真实世界的单身人士应用是“建筑师已阅读GoF书籍,并决定在任何地方填写设计模式。”或“一些卡在80年代的程序员不熟悉整个“面向对象”的东西,并希望在程序上进行编码,这意味着将数据存储为全局变量。而单例听起来像是一种“OOP”方式来制作全局变量而不会被大喊“。
关键点在于,单身人士将两个非常不同的职责混合在一起。通常,您希望最多任何给定对象中的一个
。答案 1 :(得分:8)
在我的项目中,我们创建了一个记录器组件,用于将应用程序登录到不同的源(例如,基于配置的文本文件,XML和数据库)。因此,有一个日志管理器,它在应用程序中创建记录器类的唯一一个实例,用于记录消息,错误等。
答案 2 :(得分:7)
转到read it here。
根据大众需求(呃... downvote)我重现了Skeet版本:
public sealed class Singleton
{
Singleton()
{
}
public static Singleton Instance
{
get
{
return Nested.instance;
}
}
class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
这里,实例化是由对嵌套类的静态成员的第一次引用触发的,该静态成员仅在实例中发生。这意味着实现完全是懒惰的,但具有以前的所有性能优势。请注意,虽然嵌套类可以访问封闭类的私有成员,但反之则不然,因此需要在此处为内部实例。但是,这并没有引起任何其他问题,因为这个类本身就是私有的。但是,为了使实例化变得懒惰,代码有点复杂。
答案 3 :(得分:3)
我使用Singleton的一个很好的例子是在一个必须从应用程序中的几个地方调用Web服务组件的应用程序中。我需要维护状态,初始化一些字段,并维护一个调用和回调队列,所以我不能只进行静态调用。但是我希望在整个应用程序中只重用一个实例。我将这个“服务”类实现为单例,以便我可以在应用程序上调用它来响应许多不同的事件,但它们都在一个地方处理。
根据我的经验,我使用了单例,其中一个对象将在应用程序的生命周期中被多次使用,需要初始化和/或内存繁重。基本上只有一个类的实例,你可能有很多实例,这样做会很昂贵。
答案 4 :(得分:1)
假设您的问题在标题中:
我曾经使用过每个服务器只能有一个实例的COM对象。我们通过单例将它暴露给整个ASP.NET应用程序。
答案 5 :(得分:1)
请注意,此代码不是线程安全的:
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
一个线程可以进入该函数,通过测试为null然后被暂停。然后第二个线程可以启动并通过null测试。从那时起,两个线程都会在某个时刻创建自己的sungleton对象副本,其中只有一个被使用。
在C#等GC语言中,这可能无关紧要,但如果单例控制除了内存之外的其他资源,那么它确实很重要。您需要使用double-checked locking pattern来阻止它。
答案 6 :(得分:1)
当应该只有一个对象实例时,应该使用Singleton。 However, Misko Hevery has some thoughts on why Singletons are bad!
答案 7 :(得分:0)
如果您有一个资源需要花费很多时间才能初始化,并且您使用多次,例如使用ORM时的对象上下文或某种类型的连接,您可以发现单例模式很有用
显然你必须注意保持那个东西活着不会比每次重建它都花费更多。
答案 8 :(得分:0)
我使用单例的一种方法是为应用程序实现“主控制器”对象。这有点像你用VBA获得的Application对象。
此对象执行各种启动和关闭任务。它还提供了对应用程序范围设置和服务的访问。这包括命令行参数和日志记录服务的值等。
答案 9 :(得分:-1)
这不是单身,因为单身人士使用只读关键字提供线程安全性。
例如,
public sealed class Singleton
{
// private static Singleton instance; (instead of this, it should be like this, see below)
private static readonly Singleton instance = new Singleton();
static Singleton(){}
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
}
通过使用它,它将提供胎面安全性和适当的单一模式(即它与静态类别的不同)。你的单例代码不是线程安全的。
有关单身人士的更多信息,请查看以下链接: