问:什么事设计模式?
答:能够最优解决问题的一种设计方式。
那么今天来将单利设计模式,也是给自己巩固一下。
概念
见名知意,单例设计模式的单就是单个,例就是实例。也就是说该类只有一个实例的设计。
那么这种设计的好处是什么呢?优化内存,减少不必要的对象创建。
比如说win中的任务管理器,你只能打开一个,没办法打开多个,况且这个玩意还占用内存,打开多了也没用呀!对吧?
那么好处说完了,就该说怎么去设计了
分析:
- 这个类只能创建一次,所以不能让外界随便调用进行new,就需要把构造方法私有化,只能本类使用。
- 实例化只能有一个所以我们可以根据static的特性来修饰引用,因此现在可以达到只有一个实例。
- 最后我们需要抛出去一个方法用来返回实例。
这样子我们就可以完成单利模式的设计了。
设计:
class King{
//1.私有化构造器
private King(){}
//2.static修饰引用
private static King king =new King();
//3.抛出king
public static King getInit(){
retrun king;
}
}
那么我们可以发现,当我们使用类名调用geitInit时就会先执行static修饰的
private static King king =new King();在这里回执行空参构造获取实例,随后进行返回。
这里静态变量->静态方法。
因此我们在返回实例之前就已经将实例创建好了,所以这个单例模式还有个名字叫做:
饿汉式单例⬆️
懒汉式单例⬇️
那么有了饿汉,就相应的有懒汉,那么下面我们分析一下他的逻辑。
分析:
- 这个类只能创建一次,所以不能让外界随便调用进行new,就需要把构造方法私有化,只能本类使用。
- 实例化只能有一个所以我们可以根据static的特性来修饰引用,因此现在可以达到只有一个实例。
- 最后我们需要抛出去一个方法用来返回实例。
诶?我们发现他和懒汉是一样的对不对,那么怎么懒呢?那我们来看一下代码实现
设计:
class King{
//1.私有构造
private King(){}
//2.static修饰引用
private static King king;//这里我们先懒一下不去创建
//3.抛出king
public static King getInit(){
//这里判断是否是第一次调用
if(king==null){
//如果是第一次调用则创建实例,否则不
king = new King();
}
//返回实例
return king;
}
}
那么通过阅读代码可以发现,在我们类名调用getInit的时候首先会去执行 private static King king;
声明引用之后什么也没赋值,然后执行到我们方法来判断是否是第一次调用,如果是第一次那么king就是空,就会创建,这时候,就会发现这个实例是我们要用到他的时候他才创建的,因此他成为懒汉式单例.
那么基础的已经完事了,我们来考虑一下他的线程安全问题
问题1:
- 如果我们现在是多线程情况下来调用此方法,会造成多个实例,就会违背单例模式的初衷
- 解决这个问题的方法则是添加同步锁
问题2:
- 假如当前类还有其他属性或方法,如果我们调用则会创建实例,占用内存,所以Java提供了更优雅的方法来创建单例模式
设计:
public enum King{
KING;
}
由于枚举类的特性:
- 第一行为枚举项就是此枚举的对象本质上是常量,被private static final修饰
- 枚举的构造方法是私有的
那么私有构造有了,对象有了,也可以类名直接调用那他就是个单例模式呀。