C# 单例模式在现实世界中的应用是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/733842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the real world applications of the singleton pattern?
提问by blitzkriegz
Duplicate
复制
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;
}
}
}
回答by John Saunders
Assuming your question is in the title:
假设您的问题在标题中:
I once worked with a COM object that could only have one instance per server. We exposed it to the entire ASP.NET application through a singleton.
我曾经使用过一个 COM 对象,它每个服务器只能有一个实例。我们通过单例将它暴露给整个 ASP.NET 应用程序。
回答by John Saunders
Note that this code is not thread safe:
请注意,此代码不是线程安全的:
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
One thread could enter the function, get past the test for null and then be suspended. A second thread could then start and get past the null test. From that point on, both threads will at some point create their own copy of the sungleton object, only one of which gets used.
一个线程可以进入该函数,通过 null 测试然后被挂起。然后可以启动第二个线程并通过空测试。从那时起,两个线程都会在某个时候创建自己的 sungleton 对象副本,其中只有一个被使用。
This may not matter so much in a GC language like C#, but if the singleton controls rresources other than memory, then it does matter. You need to use the double-checked locking patternto prevent it.
这在像 C# 这样的 GC 语言中可能没有那么重要,但是如果单例控制内存以外的资源,那么它确实很重要。您需要使用双重检查锁定模式来防止它。
回答by Rich
A good example of where I've used a Singleton is in an application that had to call a web service component from several places within the application. I needed to maintain state, initialize some fields, and maintain a queue of calls and callbacks, so I couldn't just make static calls. But I wanted only one instance to be reused throughout the application. I implemented this "service" class as a singleton, so that I could call it all over the app in response to many different events, but they were all handled in one single place.
我使用 Singleton 的一个很好的例子是在一个应用程序中,该应用程序必须从应用程序内的多个位置调用 Web 服务组件。我需要维护状态,初始化一些字段,并维护一个调用和回调队列,所以我不能只进行静态调用。但我只想在整个应用程序中重用一个实例。我将这个“服务”类实现为一个单例,这样我就可以在应用程序中调用它来响应许多不同的事件,但它们都在一个地方处理。
In my experience, I've used singletons where an object was going to be used many times over the life of the app, required initialization, and/or was memory heavy. Basically where having only one instance of a class where you could potentially have many instances and it would be costly to do so.
根据我的经验,我使用过单例,其中一个对象将在应用程序的生命周期中多次使用,需要初始化,和/或内存很重。基本上只有一个类的一个实例,你可能有很多实例,这样做会很昂贵。
回答by xian
You should use a Singleton when there should only be one instance of an object. However, Misko Hevery has some thoughts on why Singletons are bad!
当对象只有一个实例时,您应该使用单例。然而,Misko Hevery 对单身人士为什么不好有一些想法!
回答by pomarc
You could find the singleton pattern useful if you have a resource that costs a lot to get initialized, and that you use several times, such as an object context when you use an ORMor a connection of some sort.
如果您有一个资源需要大量初始化并且多次使用,例如使用ORM或某种连接时的对象上下文,那么您会发现单例模式很有用。
Obviously you must pay attention that keeping that thing alive does not cost you more than recreating it every time.
显然,您必须注意保持那个东西活着不会比每次重新创建它花费更多。
回答by Clayton
One way I've used a singleton is to implement a "main controller" object for an application. This was a bit like the Application object you get with VBA.
我使用单例的一种方法是为应用程序实现一个“主控制器”对象。这有点像您使用 VBA 获得的 Application 对象。
This object performed various startup and shutdown tasks. It also provided access to application-wide settings and services. This included values of command-line parameters and the logging service, among others.
该对象执行各种启动和关闭任务。它还提供了对应用程序范围设置和服务的访问。这包括命令行参数和日志服务等的值。
回答by jalf
Simple. What does a singleton do?
简单的。单例有什么作用?
- It provides global access to an instance of an object, and
- It guarantees that no more than one instance of that type can everbe created.
- 它提供对对象实例的全局访问,以及
- 这保证了该类型的不超过一个实例可以不断被创建。
So you use a singleton when you need bothof these things.
因此,当您需要这两样东西时,您可以使用单例。
And that is rare. Globals are generally speaking, bad. We tend to avoid them when possible. And building your application around the assumption that "if more than one instance exists, it is an error" is dangerous, because you typically find out the assumption didn't hold. Perhaps you want to be able to create multiple instances locally, for caching purposes. Perhaps it turns out you need more than one database, more than one log, or perhaps threading performance requires you to give each thread its own instance.
这是罕见的。全局变量一般来说是不好的。在可能的情况下,我们倾向于避免它们。并且围绕“如果存在多个实例,这是一个错误”的假设构建应用程序是危险的,因为您通常会发现该假设不成立。也许您希望能够在本地创建多个实例,用于缓存目的。也许事实证明您需要多个数据库、多个日志,或者线程性能要求您为每个线程提供自己的实例。
In any case, you don't need to enforce the "only one instance may exist" assumption. If you only need one instance, simply create only one instance. But leave the constructor publicly visible so that more instances can be created if it turns out to be necessary.
在任何情况下,您都不需要强制执行“可能仅存在一个实例”的假设。如果您只需要一个实例,只需创建一个实例即可。但是让构造函数公开可见,以便在必要时可以创建更多实例。
In other words, both of the features offered by a singleton are actually negatives. In general, we don't wantour data to be globally visible, and we don't wantto take away flexibility for no reason.
换句话说,单例提供的两个特性实际上都是否定的。一般来说,我们不希望我们的数据在全球范围内可见,我们也不想无缘无故地剥夺灵活性。
If you do need one of the features offered by a singleton, implement that one feature, without the other. If you need something to be globally accessible, make it a global. Not a singleton. And if you do need to enforce that only one instance will exist (I can't think of any plausible situations where you'd want this), then implement that, without the global visibility.
如果您确实需要单例提供的功能之一,请实现该功能,而不需要其他功能。如果你需要一些东西可以在全球范围内访问,那就让它成为全球性的。不是单身狗。如果您确实需要强制只存在一个实例(我想不出任何您想要的情况),那么在没有全局可见性的情况下实现它。
The only real world application of singletons I've ever seen has been "an architect has read the GoF book, and decided to cram design patterns in everywhere.", or "some programmer stuck in the 80's isn't comfortable with the whole "object oriented" thing, and wants to code procedurally, which means storing data as globals. And singletons sounds like an "OOP" way to make globals without getting yelled at".
我见过的唯一真实世界的单例应用是“一位架构师读了 GoF 的书,并决定在任何地方都塞满设计模式。”,或者“一些被困在 80 年代的程序员对整体不满意”面向对象”的东西,并希望按程序进行编码,这意味着将数据存储为全局变量。而单例听起来像是一种“OOP”方式来制作全局变量而不会被大喊大叫”。
The key point is that a singleton mixes two, very different, and each very rarely needed, responsibilities. Typically, you want at mostone of those in any given object.
关键在于,单身人士混合了两种非常不同且几乎不需要的职责。通常,您最多需要任何给定对象中的一个。
回答by Andrei R?nea
Jon Skeet, THE_SKEET, has a great article exemplifying various ways to implement correctly (Thread safe, lazy, performant) the Singleton pattern.
Jon Skeet, THE_SKEET有一篇很棒的文章,举例说明了正确实现单例模式(线程安全、惰性、高性能)的各种方法。
Go read it here.
去这里阅读。
By popular demand (er... downvote) I reproduce the Skeet version:
应大众需求(呃……投反对票),我重现了飞碟版:
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();
}
}
Here, instantiation is triggered by the first reference to the static member of the nested class, which only occurs in Instance. This means the implementation is fully lazy, but has all the performance benefits of the previous ones. Note that although nested classes have access to the enclosing class's private members, the reverse is not true, hence the need for instance to be internal here. That doesn't raise any other problems, though, as the class itself is private. The code is a bit more complicated in order to make the instantiation lazy, however.
在这里,实例化是由对嵌套类的静态成员的第一个引用触发的,它只发生在 Instance 中。这意味着实现是完全惰性的,但具有之前实现的所有性能优势。请注意,尽管嵌套类可以访问封闭类的私有成员,但反之则不然,因此这里需要将实例设为内部。不过,这不会引起任何其他问题,因为类本身是私有的。然而,为了使实例化延迟,代码稍微复杂一些。
回答by rakesh kumar
In my project we created a logger component which is getting used for logging in the application to different sources (e.g. text file, XML, and database, based on configurations). So there is a log manager which creates the only one instance of the logger class across the application for logging the message, errors, etc.
在我的项目中,我们创建了一个记录器组件,用于将应用程序登录到不同的源(例如,基于配置的文本文件、XML 和数据库)。所以有一个日志管理器,它在整个应用程序中创建记录器类的唯一一个实例,用于记录消息、错误等。
回答by Ritish
This is not a singleton as a singleton provides the thread safety with readonly keywords.
这不是单例,因为单例通过 readonly 关键字提供线程安全。
For example,
例如,
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;
}
}
}
By using this it will provide the tread safety and proper singleton pattern (that is how it is different from a static class). Your code for the singleton were not thread safe.
通过使用它,它将提供胎面安全和适当的单例模式(这就是它与静态类的不同之处)。您的单例代码不是线程安全的。
For more about singleton, check these links:
有关单身人士的更多信息,请查看以下链接: