Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 关于设计模式:我应该在什么时候使用singleton?_Design Patterns_Singleton - Fatal编程技术网

Design patterns 关于设计模式:我应该在什么时候使用singleton?

Design patterns 关于设计模式:我应该在什么时候使用singleton?,design-patterns,singleton,Design Patterns,Singleton,美化的全局变量-成为美化的全局类。有人说打破了面向对象的设计 请给出一些场景,而不是使用singleton的好的旧记录器。管理到数据库的连接(或连接池) 我还将使用它来检索和存储外部配置文件上的信息。当您需要管理共享资源时,可以使用单例。例如,打印机后台打印程序。应用程序应该只有一个后台处理程序实例,以避免对同一资源的请求冲突 或者数据库连接或文件管理器等。使用单例的方法之一是覆盖一个实例,其中必须有一个“代理”来控制对资源的访问。Singleton在Logger中很好,因为他们代理访问(比如)

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

请给出一些场景,而不是使用singleton的好的旧记录器。

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


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

当您需要管理共享资源时,可以使用单例。例如,打印机后台打印程序。应用程序应该只有一个后台处理程序实例,以避免对同一资源的请求冲突


或者数据库连接或文件管理器等。

使用单例的方法之一是覆盖一个实例,其中必须有一个“代理”来控制对资源的访问。Singleton在Logger中很好,因为他们代理访问(比如)只能以独占方式写入的文件。对于日志之类的东西,它们提供了一种将写操作抽象到日志文件之类的东西的方法——您可以将缓存机制包装到您的单例中,等等


还可以考虑这样一种情况:您的应用程序有许多窗口/线程/等,但需要一个通信点。我曾经用它来控制我希望应用程序启动的作业。singleton负责序列化作业,并向程序中感兴趣的任何其他部分显示它们的状态。在这种情况下,您可以将单例视为类似于在应用程序中运行的“服务器”类。。。在处理可插拔模块时,我将其用于封装命令行参数的对象。主程序不知道要加载的模块的命令行参数是什么(甚至不总是知道要加载的模块)。e、 例如,主加载A,它本身不需要任何参数(所以为什么它需要一个额外的指针/引用/任何东西,我不确定-看起来像污染),然后加载模块X、Y和Z。其中两个,比如X和Z,需要(或接受)参数,所以它们回叫命令行单例,告诉它接受什么参数,在运行时,他们会回拨以确定用户是否实际指定了其中的任何一个


在许多方面,如果每个查询只使用一个进程,那么处理CGI参数的单例程序也会起到类似的作用(其他mod_*方法不这样做,因此在那里是不好的——因此,有一个论点说,如果您移植到mod_perl或其他世界,您不应该在mod_CGI世界中使用单例程序)


我看到的一个具体例子是Lucene搜索索引编写器。

只读单例存储一些全局状态(用户语言、帮助文件路径、应用程序路径)是合理的。小心使用单例来控制业务逻辑-单例几乎总是以多个结尾

将特定的基础架构问题配置为单例或全局变量可能非常实用。我最喜欢的例子是依赖注入框架,它利用单例作为框架的连接点


在这种情况下,您需要依赖基础结构来简化库的使用并避免不必要的复杂性。

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

  • 控制对共享资源的并发访问
  • 将从系统的多个不同部分请求对资源的访问
  • 只能有一个对象
如果您提议的Singleton只有一个或两个这样的需求,那么重新设计几乎总是正确的选择

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


简单的日志记录器是可能有效的单例的最明显的例子,但这可能会随着更复杂的日志记录方案而改变。

在管理对整个应用程序共享的资源的访问时,应该使用单例,如果可能有同一类的多个实例,则会造成破坏。确保对共享资源的访问是线程安全的,这是一个很好的例子,说明这种模式在哪些方面至关重要


当使用单例时,您应该确保没有意外地隐藏依赖项。理想情况下,单例(与应用程序中的大多数静态变量一样)应该在执行应用程序的初始化代码时设置(对于C#可执行文件,设置为static void Main(),对于java可执行文件,设置为static void Main()),然后传递给需要它的所有其他实例化类。这有助于保持可测试性。

在我探索真理的过程中,我发现实际上使用单例的“可接受”理由很少

互联网上经常出现的一个原因是“日志”类(你提到过)。在这种情况下,可以使用单例而不是类的单个实例,因为日志类通常需要被项目中的每个类反复使用。如果每个类都使用这个日志类,依赖项注入就会变得很麻烦

日志记录是“可接受”单例的一个特定示例,因为它不会影响代码的执行。禁用日志记录,代码执行保持不变。启用它,相同。Misko用下面的方式说:“这里的信息是单向流动的:从应用程序流入记录器。尽管记录器是全局状态,但由于没有信息从记录器流入应用程序,记录器是可以接受的。”

我肯定还有别的
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton instance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
public class Singleton implements ISingleton {
    private static Singleton instance;

    private Singleton() {}

    public static ISingleton instance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
public static ISingleton instance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance;
}
public class SingletonFactory {
    private static ISingleton instance;

    // Knock-knock. Single Object here
    public static ISingleton simpleSingleton() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}