单例有哪些具体的合法用途?

发布于 2024-08-18 07:29:09 字数 698 浏览 4 评论 0原文

可能的重复:
论设计模式:何时使用单例?

这个问题与一般情况下单身人士是否“被认为有害”无关。我只是想知道,根据您的经验,单例在哪些特定情况中似乎工作得很好。

编辑: 如果您想一般讨论单例的适当性和/或邪恶性,已经存在问题:13797511831

哎呀!我刚刚发现我的问题已经在这里提出:关于设计模式:何时使用单例?

Possible Duplicate:
On Design Patterns: When to use the Singleton?

This question is not about whether or not singletons are "considered harmful" in general. I just want to know, from your experience, what are some SPECIFIC SITUATIONS in which singletons seem to work well.

EDIT:
Please, if you want to discuss the appropriateness and/or evilness of singletons in general, there are aleady exising questions: 137975, 11831

Oops! I've just discovered that my question has already been asked here: On Design Patterns: When to use the Singleton?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

挽手叙旧 2024-08-25 07:29:09

我们基本上将它们用于两件事:日志记录和配置。两者都假设应用程序有一个中央配置和一个中央日志文件,并不总是有效,但在我们的大多数代码中都是有效的。我们有时也会将它们用于某些工厂类或缓存类,我们希望确保我们不会重复关键元数据。

We basically use them for two things: logging, and configuration. Both assume that the app has a central config and a central logfile, not always valid but in most of our code it is. We also use them on occasion for certain factory classes or cache classes we want to make sure we're not duplicating key metadata.

二智少女 2024-08-25 07:29:09

扩展我的评论...

这个问题措辞不好,单身人士似乎在许多情况下都能很好地工作。它应该是“在哪些特定情况下单例不会暴露其负面属性?”简而言之,“全局变量什么时候好”?

  1. 全局变量就是全局变量。

    一旦使用

    void f()
    {
    X* x = X::getInstance();
    ...
    }

    您的意大利面订单已被接受,而不是 void f(X*)

  2. 单身人士激增,并且喜欢互相依赖。 SessionManager 使用 EventManager,而 EventManager 使用 LogManager。有人希望日志文件提及当前用户的名称。 LogManager 维护者添加了 SessionManager::getInstance()->getUser()->getName();,一切都很顺利,直到 LoginManager ,它也使用 LogManager,想要记录登录失败。

  3. 单例会抑制可测试性。

    单实例属性仅在生产代码中具有半用处。您可能根本无法测试 void f() 函数,并且可能只对快乐路径进行(很少)测试。

正如您所猜测的,我对全局变量什么时候好?的回答是“从不”。 你的是什么?

Expanding my comment...

The question is poorly worded, singletons seem to work well in many situations. It should be "what are some specific situations in which singletons don't expose their negative properties?" Briefly, "when are global variables good"?

  1. A global variable is a global variable.

    As soon as you use

    void f()
    {
    X* x = X::getInstance();
    ...
    }

    instead of void f(X*), your order for the spaghetti dish has been accepted.

  2. Singletons proliferate, and like to depend on each other. SessionManager uses EventManager which uses LogManager. Someone wants the log files to mention the name of the current user. The LogManager maintainer adds SessionManager::getInstance()->getUser()->getName();, everything's roses until the LoginManager, which also uses LogManager, wants to log a login failure.

  3. Singletons inhibit testability.

    The single-instance property is semi-useful only in production code. You may be unable to test the void f() function at all, and probably will have (few) tests only for the happy path.

As you can guess, my answer to when are global variables good? is "never". What is yours?

小姐丶请自重 2024-08-25 07:29:09

生成随机数序列 - 随机生成器应该是唯一的,而不是每次使用时都实例化。人们可能希望将其实现为线程级单例;然而,在这种情况下,整个过程的单例仍然是合适的。

Generating a sequence of random numbers - the random generator should be unique, not instantiated for each use. One might want to implement this as a thread-level singleton; however, a singleton for the whole process is still appropriate in this case.

杯别 2024-08-25 07:29:09
  • 当您的域指定您正在建模的事物只存在一个唯一实例时,

我仍然认为应该避免单例(至少在 Java 中)。

有两个不同的事情需要考虑:强制单例模式的概念机制

单例的概念有很多用途,日志记录、配置,更不用说当您正在工作的域实际上拥有只有一个实例的事物并且您希望对其进行建模时。也就是说,一家公司只有一个费用处理办公室,将费用表格发送到无效的办公室是错误的,该办公室实际上是一个单一的办公室。单例的概念有许多合法的用途。

然而,通常是导致问题的机制。在 Java 中,我们强制不能通过声明构造函数 private 来构造对象,这样做的问题是我们还必须通过以下方式提供实例的全局访问点具体类。这将应用程序中的所有内容都耦合到该具体类,这些类不能在运行时更改,也不能在单元测试中模拟。这种机制被认为是邪恶的——特别是在可测试性方面。

如果单例的概念可以和那些糟糕的机制分开的话,它们就不会那么邪恶了。我能想到的一个例子是 Guice 中可用的 @Singleton 作用域。在 Guice 的上下文中,它保证一个实例,但它无法通过邪恶的私有构造函数/全局访问点机制来实现这一点。

  • When your domain specifies that there only exists one unique instance of something you're modelling

I still believe singletons should be avoided (in Java at least).

There's two different things to consider: the concept and the mechanism for enforcing the Singleton pattern.

The concept of Singletons have many uses, logging, configuration, not to mention when the domain you're working actually has things where there is ever only one instance of them and you wish to model that. I.e. a company only has a single expenses processing office and sending expense forms to an invalid office is wrong, the office is in reality a singleton. The concept of a singleton has many legitimate uses.

However, it's usually the mechanism that causes the problem. In Java we enforce an object can't be constructed by declaring the constructor private, the problem with this is we also have to provide a global point of access to the instance through the concrete class. This couples everything in your application to that concrete class, which can't be changed at run-time, or mocked in unit testing. It's this mechanism which is considered evil - particularly in terms of testability.

If the concept of Singletons can be separated from the poor mechanisms, they would not be so evil. One example, I can think of is the @Singleton scope available in Guice. In the context of Guice, it guarantees one instance, but it doesn't achieve this with the evil private constructor/global point of access mechanism.

你怎么敢 2024-08-25 07:29:09

系统连接有一个设备/硬件,为了正确使用它,需要一个中心控制点。

There is a single device/hardware attached to the system and a central point of control is necessary in order to use it properly.

江南月 2024-08-25 07:29:09
  • 日志记录。

  • 查找本地化字符串资源,例如Strings.get("CONFIRM_DELETE")

这两件事都不是应该在对象的公共接口中公开的细节,因此在这里使用单例是有意义的。

  • Logging.

  • Finding localized string resources e.g. Strings.get("CONFIRM_DELETE").

Both of these things are not details that should be exposed in the public interface of your objects, so it makes sense to use a singleton here.

独闯女儿国 2024-08-25 07:29:09

我只是非常努力地在我当前正在进行的项目中摆脱单例。它们有气味,但有时很难避免。

我的情况是,我有一个 API,它构造单例对象来处理安全、配置等管理功能。该 API 使用 EntityFramework,还引入了插件(使用 MEF)。由于这些类的构造并不总是由我的代码执行(特别是对于 EF 实体),因此并不总是能够优雅地将它们注入到 biz 对象中。所以我使用了单例,它可以在项目内的任何地方访问到继承人的范围。

I just worked really hard getting rid of Singletons in the current project I am working on. They have a smell, but sometimes are very difficult to avoid.

My situation was that I had an API which constructed singleton objects for handling management functions such as Security, Configuration, etc. The API used EntityFramework and also pulled in PlugIns (using MEF). Because the construction of these classes was not always performed by my code (particularly for EF entities), it was not always possible to inject these into biz objects elegantly. So I used singletons, which can be accessed anywhere within a project subject tot heir scope.

岁月打碎记忆 2024-08-25 07:29:09

主服务器接收来自客户端的请求,并将这些请求传递给从属进程。从属进程可以使用单例与主服务器通信。

Master server takes requests from clients, and passes these requests off to a subordinate process. The subordinate process may use a singleton for communicating with the master server.

缘字诀 2024-08-25 07:29:09

我尽量不依赖 Singleton,但我更喜欢解耦而不是不使用 Singleton。因此,我经常将 Singleton 与 Prototype 模式结合使用,它允许在库加载时注册 Prototypes(全局对象构造)。

我正在编写一个由多个库组成的服务器。有许多“通用”库,然后每个服务有一个库。 “主”库的任务是查看收到的消息并根据密钥调用正确的服务...这使用了一个简单的 std::map

对地图使用单例可以让我拥有完全解耦的代码。没有任何库依赖于我的服务库,我的服务库之外的任何代码行都没有负责注册其服务。事实上,我可以通过在编译时更改“链接”命令来决定嵌入哪些服务:如果我不链接库,则不会嵌入其服务。

我真的发现它在那里很有用......对于配置,我更喜欢使用 MonoPattern:即所有实例共享相同数据的普通类(从而包装真正的单例)。使迁移更容易,以防万一有必要,因为客户不知道他们正在使用单例卧底。

I try not to rely on Singleton, however I prefer decoupling to not using Singleton. Thus, I often use Singleton coupled with the Prototype pattern, which allow for registering the Prototypes at library load (global objects construction).

I am writing a server consisting of a number of libraries. There is a number of "common" libraries, then one library per service. A "main" library is tasked with the purpose of looking at the message received and invoked the right service depending on a key... This uses a simple std::map.

Using a Singleton for the map allow me to have totally decoupled code. No library depends on my service library, no line of code outside my service library is tasked with registering its service. In fact, it is such that I can decide which services are embedded simply by altering my "link" command at compile-time: if I do not link with a library, its service is not embedded.

I really find it useful there... for configuration and such I prefer to use the MonoPattern: ie normal looking class with all instances sharing the same data (thus wrapping a real singleton). Makes for easier migration just in case it's necesary since the clients don't know they are using a Singleton undercover.

々眼睛长脚气 2024-08-25 07:29:09

除了日志记录(正如大多数其他人已经提到的那样)之外,我还使用单例来实现控制反转 (IoC) 容器。依赖项在应用程序启动时注册一次,并且可以使用单例方法在应用程序期间的任何时间点解析依赖项。

In addition to logging (as most others have already mentioned), I've used singletons for Inversion of Control (IoC) Containers. The dependencies are registered once at the start of the application, and one can resolve a dependency at any point in time during the app using the singleton method.

始终不够 2024-08-25 07:29:09

它们非常适合您希望视为独特资源的项目。

作为 Web 系统中的示例,您可能希望仅对所提供的每个页面使用单个数据库连接 - 在这种情况下,使用单例模式是有意义的。 (尽管您必须在知道数据库访问对象是单例的情况下进行编码,这不太理想,但如果有明确的文档记录等,则可以接受)

They're good for items that you wish to consider as unique resources.

As an example in web systems you may wish to only use a single database connection for each page that's served - in this instance using the singleton pattern would make sense. (Although you'd have to code with the knowledge that the database access object was a singleton, which is less ideal, but acceptable if clearly documented, etc.)

听,心雨的声音 2024-08-25 07:29:09

当程序的一部分需要一个实现特定接口(多态性)的对象时,但您永远不需要该对象的多个实例。否则静态方法就可以了。

When a part of your program needs an object that implements a specific interface (polymorphism-wise), but you never want more than a single instance of that object. Otherwise static methods will do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文