一个案例搞懂工厂模式和单例模式
一个案例搞懂工厂模式和单例模式
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 工厂模式
/**
* 一开始,穷,想吃面必须得自己做
* 想吃拉面得自己做,new LzNoodles()
* 想吃泡面得自己做,new PaoNoodles()
* 想吃热干面得自己做,new ReganNoodles()
*/
// 做拉面吃
INoodles lzNoodles = new LzNoodles();
// 做泡面吃
// INoodles paoNoodles = new PaoNoodles();
// 做热干面吃
// INoodles reganNoodles = new ReganNoodles();
// 然而,new来new去,改来改去,好心烦......
/**
* 忽然,有一天走了狗屎运成了暴发户
* 幸福生活从此来临,吃面从此变得简单
* 给面馆说一声想吃啥,面馆做好了给自己就好了
* 自己不必关心面条怎么做(怎么new,如何new)让面馆操心去吧(面馆帮我们new)!
* 好省心,有钱就是好,太爽了!
*/
INoodles iNoodles = SimpleNoodlesFactory.createNoodles(2); // 和具体的对象脱离关系
iNoodles.desc();
再进行演变: 考虑使用工厂模式,给个工厂生产自己的专属面条,需要吃那个创建即可。
- 工厂是负责创建对象