一个案例搞懂工厂模式和单例模式

2022-08-05

一个案例搞懂工厂模式和单例模式

1 单例模式

  • 一个对象只有一个实例
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给所有其他对象提供这一实例。

注意:所有的单例模式,应当使其构造方法私有化。

1.1 饿汉单例模式

所谓饿汉单例:就是指在类被加载时就创建自己的唯一实例。

/**
 * @author look-word
 *
 * 饿汉式(立即加载)
 */
public class HungrySingleton {

    // 构造方法私有化
    private HungrySingleton() {}

    // 将自身实例化对象设置为一个属性,并用static、final修饰
    private static final HungrySingleton instance = new HungrySingleton();

    // 静态方法返回该实例
    public static HungrySingleton getInstance() {
        return instance;
    }
}

1.2 懒汉单例模式

所谓懒汉单例模式:在使用该类时,才创建实例对象。

  • 注意:需要加上线程同步关键字
  • 可能会存在线程安全问题,多个线程同时调用
/**
 * @author 应癫
 */
public class LazySingleton {

    // 将自身实例化对象设置为一个属性,并用static修饰
    private static LazySingleton instance;

    // 构造方法私有化
    private LazySingleton() {}

    // 静态方法返回该实例,加synchronized关键字实现同步
    public static synchronized LazySingleton getInstance() {
        if(instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}
名称 优点 缺点
饿汉单例模式 多线程安全,没有加锁执行效率高。 类加载时就初始化,浪费内存。
懒汉单例模式 第一次调用才初始化,避免内存浪费。 必须加锁 synchronized 才能保证单例,但加锁会影响效率。

2 工厂模式

img

        /**
         *  一开始,穷,想吃面必须得自己做
         *  想吃拉面得自己做,new LzNoodles()
         *  想吃泡面得自己做,new PaoNoodles()
         *  想吃热干面得自己做,new ReganNoodles()
         */
        // 做拉面吃
        INoodles lzNoodles = new LzNoodles();
        // 做泡面吃
        // INoodles paoNoodles = new PaoNoodles();
        // 做热干面吃
        // INoodles reganNoodles = new ReganNoodles();

        // 然而,new来new去,改来改去,好心烦......

img

        /**
         * 忽然,有一天走了狗屎运成了暴发户
         * 幸福生活从此来临,吃面从此变得简单
         * 给面馆说一声想吃啥,面馆做好了给自己就好了
         * 自己不必关心面条怎么做(怎么new,如何new)让面馆操心去吧(面馆帮我们new)!
         * 好省心,有钱就是好,太爽了!
         */
        INoodles iNoodles = SimpleNoodlesFactory.createNoodles(2);  // 和具体的对象脱离关系
        iNoodles.desc();

再进行演变: 考虑使用工厂模式,给个工厂生产自己的专属面条,需要吃那个创建即可。

  • 工厂是负责创建对象

img