23种设计模式(五) —— 手写实现 Singleton 模式 (生成实例)

x33g5p2x  于2021-12-06 转载在 其他  
字(1.6k)|赞(0)|评价(0)|浏览(168)

Author: Gorit
Date:2021年2月
Refer:《图解设计模式》
2021年发表博文: 14/50

一、Singleton 只有一个实例(单例模式)

程序在运行的过程中,通常会出现多个实例。

比如字符串中的 java.lang.String 类的实例与字符串是一一对应的关系,所以当有 1000 个字符串的时候,会生成 1000 个实例

但是,当我们的程序中某个东西只会存在一个时,就会有 “只创建一个实例” 的需求。

比如:

  1. 程序所运行的那台计算机的类
  2. 表示软件系统,相关设置的类
  3. 以及表示视窗系统(windows system)

我们要做到只调用一次 new MyClass(),就可以达到只生成一个实例的目的。这种只生成一个实例的模式称为 Singleton模式

二、示例程序

类名功能
Singleton只存在一个实例的类,提供 getInstance() 方法
Main测试程序行为的类

2.1 饿汉模式

PS: 细分的话,单例模式还分场景(懒汉模式,恶汉模式)

package singleton;

/** * 单例模式的实现 (饿汉式) */
public class Singleton {
    private static Singleton singleton = new Singleton();
    // 禁止从外部调用构造函数,为了保证只生成一个实例,就必须这么做
    // 防止使用 new 关键字,对构造方法设置 private
    private Singleton () {
        System.out.println("生成一个实例");
    }
    // 返回实例的 static 方法
    public static Singleton getInstance() {
        return singleton;
    }
}

2.2 懒汉模式

package singleton;

/** * 懒汉式单例模式(线程不安全) */
public class SingletonLazy {
    private static SingletonLazy singletonLazy = null;
    private SingletonLazy() {
        System.out.println("实例化了");
    }
    public static SingletonLazy getInstance() {
        if (singletonLazy == null) {
            singletonLazy = new SingletonLazy();
        }
        return singletonLazy;
    }
}

2.3 枚举生成单例

package singleton;

public enum SingletonEnum {
    Singleton
}

Main

public static void main(String[] args) {
        System.out.println("Begin...");
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        if (s1 == s2) {
            System.out.println("s1 和 s2 是相同的实例");
        } else {
            System.out.println("s1 和 s2 不是相同的实例");
        }
        System.out.println("End...");
    }

执行效果

三、Singleton 模式登场的角色

  • Singleton 模式

在该模式中,只有这么一个角色,该角色有一个返回一个唯一实例的 static 方法,该方法总会返回同一个实例

四、在哪里我们用到了 Singleton

  1. 使用 Spring 框架创建 Bean 的时候,默认的 scope 就是 Bean
  2. windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
  3. 网站计数器,Java EE 中,我们可以采用 application 域来统计网站访问次数,因为 application 只会创建一次

五、源代码以及原文档

原文链接 —— 以及其他系列文章整合
源代码

相关文章