[设计模式]01_单例模式

简介


单例模式(Singleton Pattern)保证一个类只有一个实例,并提供一个访问它的全局访问点

单例模式是一种对象创建型模式可参考 设计模式 创建型模式)。

单例模式是设计模式中最简单的模式。它的用途就是使得类的一个对象成为系统中的唯一实例

结构


图-单例模式结构图

Singleton : 定义一个接口 Instance() 使得客户端可以访问它的唯一实例。

动机


在以下情况中,可以考虑应用单例模式:

  • 保证一个类只有一个实例,并提供一个访问它的全局访问点。
  • 当唯一的实例应该对子类可扩展,并且用户应该可以在不改变代码的情况下使用扩展的实例。

实际应用场景

一些资源管理器常常设计成单例模式。

在计算机系统中,需要管理的资源包括软件外部资源,譬如每台计算机可以有若干个打印机,但只能有一个Printer Spooler, 以避免两个打印作业同时输出到打印机中。

每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。任务管理器中难以启动两个相同的task。

要点


1、一个类只能有一个实例。

需要定义一个该类的静态私有变量,使这个类的所有对象都共用这个实例。

2、实例必须由类自行创建。

单例模式的类只能提供私有的构造函数。如此,才能保证外部无法实例化这个类的对象。

3、必须提供获取实例的方法。

单例模式的类必须提供一个公共的静态函数用于创建或获取它本身的静态私有对象

实例



1、懒汉式

你不找懒汉,懒汉根本就懒得去初始化自己的实例。

instance 初始时没有初始化,只有当第一次调 getInstance() 时才创建实例。

缺点:当有两个线程调
getInstance() 方法,当它们同时执行到 if (null == instance) 这行代码,instancenull

继续向下执行,会生成两个实例,违背了单例模式的初衷。

public class LazySingleton {
    private LazySingleton() {
        System.out.println("Singleton()");
    }

private static LazySingleton instance = null;
    
    public static LazySingleton getInstance() {
        if (null == instance) {
            instance = new LazySingleton();
        }        
        return instance;
    }
}

2、饿汉式

饿汉根本等不及别人来找他,不管三七二十一先初始化了自身的实例,生怕自己饿着了。

类默认先直接初始化一个实例,以后调用 getInstance() 总是返回这个已创建好的实例。

缺点:在没有必要获取实例时,已经预先产生了开销。

优点:规避了懒汉式方法的线程问题,不用显示编写线程安全代码。

public class HungerSinleton {
    private HungerSinleton() {
        System.out.println("Singleton()");
    }
    
    private static HungerSinleton instance = new HungerSinleton();
    
    public static HungerSinleton getInstance() {
        return instance;
    }
}

3、双重锁的形式

如果既不想在没有调用 getInstance()
方法时产生开销,又不想发生线程安全问题,就可以采用双重锁的形式。

public class SyncSingleton {
    private SyncSingleton() {
        System.out.println("Singleton()");
    }
    
    private static SyncSingleton instance = null;
    
    public static SyncSingleton getInstance() {
        if (null == instance) {
            synchronized(SyncSingleton.class) {
                if (null == instance) {
                    instance = new SyncSingleton();
                }
            }
        }
        return instance;
    }
}

注:在外面判断了instance实例是否存在,为什么在锁定后又要在内部又判断一次?

这是因为,如果 instance null 时有两个线程同时调用 getInstance(),由于
synchronized
机制,只有一个线程可以进入,另一个需要等待。

这时如果没有第二道 instance 是否为 null
的判断,就可能发生第一个线程创建一个实例,而第二个线程又创建一个实例的情况。

C++版单例模式

下面是一个采用饿汉式的例子

#include "stdafx.h"
#include <iostream>
using namespace std;

class Singleton
{
private:
    static Singleton *m_instance;
    Singleton()
    {
        cout << "Singleton Construct" << endl;
    }
public:
    static Singleton* GetInstance()
    {
        return m_instance;
    }
};

Singleton* Singleton::m_instance = new Singleton();

int main()
{
    //Singleton *pSingletonA = new Singleton;  //编译会报错,因为不能访问私有函数
    Singleton *pSingletonA = Singleton::GetInstance();
    Singleton *pSingletonB = Singleton::GetInstance();

if (pSingletonA == pSingletonB)
        cout << "Same Instance" << endl;
    return 0;
}

推荐阅读


本文属于 设计模式系列

参考资料


《大话设计模式》

《HeadFirst设计模式》

时间: 2024-08-12 12:10:13

[设计模式]01_单例模式的相关文章

Java设计模式:单例模式

概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器的功能.每台计算机可以有若干个打印机,但只能

[转]JAVA设计模式之单例模式

原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话

设计模式 之 单例模式

单例模式思路: 私有化构造方法: 防止实例化 私有化克隆方法: 防止克隆 私有化静态属性: 保存对象 公有化静态方法: 获取对象 代码: <?php //设计模式:单例模式 class Singleton { //私有化静态属性:用于保存对象 private static $obj; //私有化构造方法 private function __construct(){} //公有化静态方法:用于实例化对象 public static function getObj() { //判断对象是否存在 i

设计模式实例学习-单例模式(Android中的使用场景)

1.设计模式实例-单例模式 单例模式,故名思议,是指在一个类中通过设置静态使得其仅创造一个唯一的实例.这样设置的目的是满足开发者的希望--这个类只需要被实例化创建一次,同时因为其为静态的缘故,加载的速度也应该快于正常实例化一个类的速度(理论上). 在Android开发中,当我们需要创建一个Fragment的时候常常会用到这样的模式,没有代码的学习是虚无的,接下来亮代码学习: public class SelectFrame extends Fragment { private final sta

(九)JAVA设计模式之单例模式

JAVA设计模式之单例模式 一.单例模式的介绍 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点.     全局对象和Singleton模式有本质的区别,因为大量使用全局对象会使得程序质量降低,而且有些编程语言根本不支持全局变量.最重要的是传统的全局对象并不能阻止一个类被实例化多次. 二.单例模式的特点 单例类只能有一个实例 单例类必须自己创建自己的唯一实例. 单例类必须给所有其他对象提供这一实例.

C#设计模式(1)——单例模式

一.引言 最近在设计模式的一些内容,主要的参考书籍是<Head First 设计模式>,同时在学习过程中也查看了很多博客园中关于设计模式的一些文章的,在这里记录下我的一些学习笔记,一是为了帮助我更深入地理解设计模式,二同时可以给一些初学设计模式的朋友一些参考.首先我介绍的是设计模式中比较简单的一个模式——单例模式(因为这里只牵涉到一个类) 二.单例模式的介绍 说到单例模式,大家第一反应应该就是——什么是单例模式?,从“单例”字面意思上理解为——一个类只有一个实例,所以单例模式也就是保证一个类只

.NET设计模式之(单例模式)

1.单例模式,一个类只能new一个对象 2.举例,资源管理器,文件管理器,地球等: 3.创建单例: (1)创建一个Earth类 class Earth { public Earth() { } } (2)将构造函数 私有化 class Earth { private Earth() { } } (3)声明一个静态私有的字段,初始化一个实例 class Earth { private static Earth instance=new Earth(); private Earth() { } }

Java 设计模式(3)单例模式

前言 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些应用都或多或少具有资源管理器的功能.每台计算机可以有若干个打印机,

设计模式【单例模式】

Java中单例模式是一种常见的设计模式,单例模式分为:饿汉式单例模式.懒汉式单例模式.登记式单例模式.枚举式单例模式.作为对象的常见模式的单例模式,确保某一类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类必须给所有其他对象提供这一实例. 举例说明:在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实