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)懒汉式:不存在资源浪费问题

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