`

03 Singleton 模式

 
阅读更多

转自:http://www.riabook.cn/doc/designpattern/

Design Pattern: Singleton 模式

 

Singleton的英文意义是独身,也就是只有一个人,应用在物件导向语言上,通常翻译作单例:单一个实例(Instance)。

很多时候,您会需要Singleton模式,例如印表机管理,您希望程式中只能有一个Print Spooler,以避免两个列印动作同时输入至印表机中;例如资料库管理,因为建立连接(Connection)物件会耗用资源,您希望程式中只能有一个 连接物件,所有其它的程式都透过这个物件来连接资料库,以避免连接物件的重复开启造成资源的耗用;例如系统程式属性档的读取,您使用单一个物件来读取属性 内容,而程式的其它部份都向这个物件要求属性资料,而不是自行读取属性资料。

以印表机设计为例,有的设计人员会采取全域变数的方式来建立实例,并在程式中随机取用这个实例,Java虽然不支援全域变数,但透过将物件包装在一个类别之中,也有人会采用这样的写法:

 

public class PrintSpooler { 
    public PrintSpooler() { 
        // .... 
    } 

    public Connection getSpooler(){ 
       .... 
    } 
} 

 public class GlobalObject { 
    private PrintSpooler printSpooler; 
    public GlobalObject () { 
        printSpooler = new PrintSpooler(); 
        ... 
    } 
    
    public void getPrintSpooler() { 
        return printSpooler; 
    } 
 }

 

无论全域变数或是以上的例子,都无法保证只产生唯一个实例,您也许会注意不犯这个错误,但与您共同工作的伙伴也许会直觉的使用建构方法来产生一个 PrintSpooler实例。

Singleton模式可以保证一个类别只有一个实例,并提供一个访问(visit)这个实例的方法。

一个Singleton实作即为Java中的java.lang.Runtime类别,每个Java程式执行时都有一个唯一的Runtime物件,可以透过它提供的静态方法getRuntime()方法来取得这个物件,例如:
Runtime runtime = Runtime.getRuntime();

取得Runtime物件之后,您可以透过它进行一些外部命令的执行、进行垃圾处理等等指令,您可以开启Runtime.java类别,开头的几行是这样写的:

public class Runtime { 
    private static Runtime currentRuntime = new Runtime(); 

    public static Runtime getRuntime() { 
        return currentRuntime; 
    } 

   /** Don't let anyone else instantiate this class */ 
   private Runtime() {} 

    // 以下略 
}

 

上面结构即采用Singleton模式设计,其结构使用 UML 来表即如下所示:



 如上所示的,Java使用 静态工厂 来取得Runtime物件,其中Runtime的建构函式被宣告为private,这样可以阻止其他人使用建构方法来建立实例;使用更一般化的表示单例的UML结构,如下图所示:



 有几个实作上面结构的方法,可以在第一次需要实例时再建立物件,也就是采用所谓的Lazy Initialization:

public class Singleton { 
    private static Singleton instance = null; 

    private Singleton() { 
        // .... 
    } 

    public static Singleton getInstance() { 
        if (instance == null) {
            instance = new Singleton(); 
        }

        return instance; 
    } 

    // .. 其它实作 
}

 

上面的实作适用于单执行绪的程式,在多执行绪的程式下,以下的写法在多个执行绪的竞争资源下,将仍有可能产生两个以上的实例,例如下面的情况:

Thread1: if(instance == null) // true
Thread2: if(instance == null) // true

Thread1: instance = new Singleton(); // 产生一个实例
Thread2: instance = new Singleton(); // 又产生一个实例

Thread1: return instance; // 回传一个实例
Thread2: return instance; // 又回传一个实例

 

在多执行绪的环境下,为了避免资源同时竞争而导致如上产生多个实例的情况,加上同步(synchronized)机制:

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

 

不过这种简单的写法不适合用于像伺服器这种服务很多执行绪的程式上,同步机制会造成相当的效能低落,为了顾及Singleton、Lazy Initialization与效能问题,因而有了Double-check Locking的模式:

public class Singleton {
    private static Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance() {
        if (instance == null){
            synchronized(Singleton.class){
                if(instance == null) {
                     instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

 Java中Runtime类别的作法就简单多了,它舍弃了Lazy Initialization,如果您的实例初始化不是很久的话,可以用这种方式:

public class Singleton { 
    private static Singleton instance = new Singleton(); 

    private Singleton() { 
        // .... 
    } 

    public static Singleton getInstance() { 
        return instance; 
    } 

    // 其它实作 
}

 Singleton本身的观念简单但应用很广,因而很多时候必须对实际环境作一些考量与调整,建议您也看看有关于Singleton的这篇 讨论。

  • 大小: 10 KB
  • 大小: 10.3 KB
分享到:
评论

相关推荐

    C++完美实现Singleton模式

    ### C++中实现Singleton模式的关键知识点 #### 一、Singleton模式简介 Singleton模式是一种常用的软件设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点。这种模式在系统中经常被用于控制对共享资源...

    C++ 实现的singleton 模式

    **C++实现的Singleton模式详解** Singleton模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,例如管理共享资源,如数据库连接池,或者确保某个...

    Java常用设计模式(SingleTon、FactoryMethod、AbstractFactory)

    这里我们将深入探讨三种常见的Java设计模式:单例(Singleton)、工厂方法(Factory Method)和抽象工厂(Abstract Factory)。 **单例模式(Singleton)** 单例模式确保一个类只有一个实例,并提供一个全局访问点...

    (创建型模式)Singleton模式

    Singleton模式是设计模式中的一种创建型模式,它在软件工程中扮演着重要的角色。这个模式的主要目的是确保一个类只有一个实例,并提供一个全局访问点来获取这个唯一的实例。Singleton模式的应用场景通常涉及到系统...

    Java的Singleton模式代码(免资源分)

    ### Java的Singleton模式详解 #### 一、Singleton模式概述 Singleton模式是一种常用的设计模式,在Java中主要用于确保一个类只有一个实例,并提供一个全局访问点。这种模式对于管理共享资源(如数据库连接池、...

    最简单的设计模式学习Singleton模式

    ### 最简单的设计模式学习:Singleton模式 #### 一、Singleton模式简介 Singleton(单例)模式是一种常用的软件设计模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在许多场合下非常...

    设计模式 创建型模式 Singleton模式(单键)

    Singleton模式: 确保一个类只有唯一的一个实例。 Singleton主要用于对象的创建,这意味着,如果某个类采用了Singleton模式,则在这个类被创建后,它将有且仅有一个实例可供访问。很多时候我们都会需要Singleton...

    Qt qml Singleton 单例模式

    综上所述,Qt Qml的Singleton模式为全局共享对象提供了方便,使得在Qml环境中管理和访问同一对象变得简单。通过C++和Qml的有效结合,我们可以构建出高效且易于维护的应用程序。了解和熟练运用Singleton模式,对于...

    C#设计模式之Singleton模式

    《C#设计模式之Singleton模式详解》 Singleton模式是软件设计模式中的一种基础模式,它在众多设计模式中占有重要地位,尤其在C#编程中经常被应用。Singleton模式的主要目的是确保一个类只有一个实例,并提供一个...

    Singleton模式源程序

    Singleton模式是一种设计模式,它是创建型模式的一种,用于控制类的实例化过程,确保一个类在整个应用程序中只有一个实例存在。这种模式在系统中需要频繁创建和销毁对象,且对象需要共享资源时非常有用,比如配置...

    Java线程安全的Singleton模式:深入分析与实现

    在Java编程中,Singleton模式是一种常用的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。线程安全的Singleton模式对于多线程环境尤为重要,因为它可以防止多个线程同时创建多个实例。本文将详细介绍...

    singleton设计模式java实现及对比

    在Java中,Singleton模式的实现有多种方式,每种方式都有其优缺点,我们将详细探讨这些实现方法并进行对比。 ### 1. 饿汉式(Static Final Field) 这是最简单的Singleton实现方式,通过静态初始化器在类加载时就...

    java Singleton单例模式

    接下来,我们将深入探讨Java Singleton模式的实现方式、优缺点以及使用场景。 一、Singleton模式的实现 1. 饿汉式(静态常量) ```java public class Singleton { private static final Singleton INSTANCE = ...

    Singleton模式

    Singleton模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。这个模式在许多场景下非常有用,比如配置管理、日志服务、线程池等,需要确保全系统内只有一个对象来处理特定任务的情况...

    深入浅出单例Singleton模式

    【深入浅出单例Singleton模式】 单例模式是一种在软件设计中常见的设计模式,它的核心目标是确保一个类只有一个实例,并提供一个全局访问点。在Java等面向对象编程语言中,单例模式常用于控制资源的共享,如全局...

    C#面向对象设计模式纵横谈-1.Singleton 单件(创建型模式)

    Singleton模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个唯一的实例。这种模式在需要控制资源的唯一性或者全局访问点时非常有用,比如数据库连接、线程池或者缓存管理等。 ...

    单例模式Singleton(java源码)

    Singleton模式包含的角色只有一个,就是Singleton。Singleton拥有一个私有构造函数,确保用户无法通过new直接实例化它。除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance()...

Global site tag (gtag.js) - Google Analytics