Skip to content

单例设计模式


基本介绍 ​

1. 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中 ​

(1)对某个类只能存在一个对象实例 ​

(2)并且该类只提供一个获取对象实例的方法 ​

实际应用 ​

javaSE 标准类中,java.lang.Runtime 就是经典的单例模式 ​

2. 分类(两种方式) ​

(1)饿汉式 ​

(2)懒汉式 ​

实现方法 ​

(1)类的内部创建对象 ​

(2)构造器私有化, 防止直接使用 new 创建对象 ​

(3)向外暴露一个静态的公共方法,用于返回对象(getinstance) ​

饿汉式 ​

(1)基本介绍 ​

只要类加载,无论是否使用该类的实例对象,都会在类中创建对象实例 ​

(2)形象理解 ​

很饿,饥渴难耐,无论是否使用该对象,都会创建 ​

代码示例 ​

java
package pattern.sigal;

public class main {
    public static void main(String[] args) {
        girlfriend instance = girlfriend.getinstance();
        System.out.println(instance);
    }
}

class girlfriend{

    private String name;
    /*
         单例模式实现三步走
        (1)类的内部创建对象
        (2)构造器私有化--->==防止直接`new`==
        (3)向外暴露一个静态的公共方法:用于返回对象(getinstance)
     */

    // 使用静态方法创建对象(gf是一个静态变量)
    private static girlfriend gf = new girlfriend("女朋友");

    // 构造器私有化
    private girlfriend(String name) {
        System.out.println("构造器被调用");
        this.name = name;
    }

    // 编写返回对象的方法(静态方法)
    public static girlfriend getinstance(){
        return gf;
    }

    // 重写 toString 方法,输出对象的属性
    @Override
    public String toString() {
        return "girlfriend{" +
                "name='" + name + '\'' +
                '}';
    }
}

// 输出结果
构造器被调用
girlfriend{name='女朋友'}

懒汉式 ​

(1)基本介绍 ​

只有在对象被使用时才会创建 ​

(2)形象理解 ​

很懒,有需求了才做 ​

代码示例 ​

java
package pattern.lazy;

public class main {
    public static void main(String[] args) {
        Cat cat = Cat.getInstance();
        System.out.println(cat);

        Cat cat1 = Cat.getInstance();
        System.out.println(cat1);

        System.out.println(cat == cat1); // 结果为 true,说明只会创建一个cat对象
    }
}

class Cat {
    private String name;
    private static Cat cat; // 使用对象时才会创建,先声明

    private Cat(String name) {
        System.out.println("构造器被调用");
        this.name = name;
    }

    public static Cat getInstance() {
        if (cat == null) {
            cat = new Cat("小猫");
        }
        return cat;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }
}

// 输出结果
构造器被调用
Cat{name='小猫'}
Cat{name='小猫'}
true

两者对比 ​

1. 创建对象的时机不同 ​

(1)饿汉式:在类加载就创建了对象实例 ​

(2)懒汉式:在使用时才创建 ​

2. 关于线程安全问题 ​

(1)饿汉式:不存在 ​

(2)懒汉式:存在 ​

3. 关于资源浪费问题 ​

(1)饿汉式:存在浪费资源的可能 ​

解释:只要类加载,就会执行创建对象实例,如果对象实例没有被使用,就造成了资源的浪费 ​

(2)懒汉式:不存在资源浪费问题 ​

解释:懒汉式模式下,对象在使用时才创建,就不存在这个问题 ​