美化的全局变量-变成一个美化的全局类。有人说打破面向对象设计。

给我一些场景,除了使用单例是有意义的良好的老记录器。


当前回答

一个实例可以在Test::Builder中找到,这个类支持几乎所有现代Perl测试模块。Builder单例存储并代理测试流程的状态和历史记录(历史测试结果,计算运行的测试次数)以及测试输出流向等内容。这些都是协调由不同作者编写的多个测试模块以在单个测试脚本中一起工作所必需的。

The history of Test::Builder's singleton is educational. Calling new() always gives you the same object. First, all the data was stored as class variables with nothing in the object itself. This worked until I wanted to test Test::Builder with itself. Then I needed two Test::Builder objects, one setup as a dummy, to capture and test its behavior and output, and one to be the real test object. At that point Test::Builder was refactored into a real object. The singleton object was stored as class data, and new() would always return it. create() was added to make a fresh object and enable testing.

Currently, users are wanting to change some behaviors of Test::Builder in their own module, but leave others alone, while the test history remains in common across all testing modules. What's happening now is the monolithic Test::Builder object is being broken down into smaller pieces (history, output, format...) with a Test::Builder instance collecting them together. Now Test::Builder no longer has to be a singleton. Its components, like history, can be. This pushes the inflexible necessity of a singleton down a level. It gives more flexibility to the user to mix-and-match pieces. The smaller singleton objects can now just store data, with their containing objects deciding how to use it. It even allows a non-Test::Builder class to play along by using the Test::Builder history and output singletons.

似乎在数据的协调和行为的灵活性之间存在着一种推拉关系,这种关系可以通过在共享数据周围使用尽可能少的行为来缓解,以确保数据的完整性。

其他回答

使用单例的方法之一是覆盖一个实例,其中必须有一个“代理”控制对资源的访问。单例在日志记录器中很好,因为它们代理访问,比如说,一个文件,这个文件只能被写入。对于像日志这样的东西,它们提供了一种方法来抽象出对日志文件之类的东西的写操作——你可以将缓存机制包装到你的单例中,等等……

也可以考虑这样一种情况,你有一个应用程序,有许多窗口/线程等,但它需要一个单一的通信点。我曾经使用它来控制我希望应用程序启动的作业。单例程序负责将作业序列化,并将它们的状态显示给程序中其他感兴趣的部分。在这种情况下,你可以把单例对象看作是在应用程序中运行的“服务器”类……HTH

一个实例可以在Test::Builder中找到,这个类支持几乎所有现代Perl测试模块。Builder单例存储并代理测试流程的状态和历史记录(历史测试结果,计算运行的测试次数)以及测试输出流向等内容。这些都是协调由不同作者编写的多个测试模块以在单个测试脚本中一起工作所必需的。

The history of Test::Builder's singleton is educational. Calling new() always gives you the same object. First, all the data was stored as class variables with nothing in the object itself. This worked until I wanted to test Test::Builder with itself. Then I needed two Test::Builder objects, one setup as a dummy, to capture and test its behavior and output, and one to be the real test object. At that point Test::Builder was refactored into a real object. The singleton object was stored as class data, and new() would always return it. create() was added to make a fresh object and enable testing.

Currently, users are wanting to change some behaviors of Test::Builder in their own module, but leave others alone, while the test history remains in common across all testing modules. What's happening now is the monolithic Test::Builder object is being broken down into smaller pieces (history, output, format...) with a Test::Builder instance collecting them together. Now Test::Builder no longer has to be a singleton. Its components, like history, can be. This pushes the inflexible necessity of a singleton down a level. It gives more flexibility to the user to mix-and-match pieces. The smaller singleton objects can now just store data, with their containing objects deciding how to use it. It even allows a non-Test::Builder class to play along by using the Test::Builder history and output singletons.

似乎在数据的协调和行为的灵活性之间存在着一种推拉关系,这种关系可以通过在共享数据周围使用尽可能少的行为来缓解,以确保数据的完整性。

管理到数据库的连接(或连接池)。

我还会使用它来检索和存储外部配置文件中的信息。

正如大家所说,共享资源——特别是不能处理并发访问的资源。

我所见过的一个具体例子是Lucene搜索索引写入器。

单例候选人必须满足三个要求:

控制对共享资源的并发访问。 将从系统的多个不同部分请求对资源的访问。 只能有一个对象。

如果你提议的单例只有其中的一两个需求,那么重新设计几乎总是正确的选择。

例如,打印机假脱机程序不太可能从多个位置(打印菜单)调用,因此可以使用互斥来解决并发访问问题。

简单的日志记录器是可能有效的单例的最明显的例子,但这可能会在更复杂的日志记录方案中发生变化。