单例模式的定义和面试重点,没事多动手对自己是没有什么坏处的

单例模式

    • 单例模式定义
      • 单例模式核心三要素(面试重点)
    • 饿汉单例模式
    • 懒汉单例模式
    • 饿汉和懒汉单例模式的调用方式
    • 饿汉单例模式和懒汉单例模式的区别
    • 单例模式小练手

这里我使用在how2j上部分解答加上自己写的一些代码,我会加上我自己的理解给大家最简单的解答。

这里的代码环境设定在LOL中。
其有一个怪叫大龙GiantDragon,只有一只,所以该类,只能被实例化一次。
我们用这个来做代码的示范。

单例模式定义

单例模式又叫做 Singleton模式,指的是一个类,在一个JVM里,只有一个实例存在。
最终造成影响很简单,就是

外部无法通过new 得到新的实例。

我们实现的方法是通过

私有化构造方法

实现的。

构造方法晓得不?这个不知道我们可以百度或者再写一篇给你介绍介绍。

单例模式核心三要素(面试重点)

  1. 私有化构造方法
  2. 定义私有静态 (类)属性指向实例
  3. public static(公共静态(或者类))的 (getInstance)方法返回第二步的静态属性

如果不理解,我们可以通过代码进一步深入理解

饿汉单例模式

GiantDragon 提供了一个public static的getInstance方法,外部调用者通过该方法获取定义的对象,而且每一次都是获取同一个对象。 从而达到单例的目的。
这种单例模式又叫做饿汉式单例模式,无论如何都会创建一个实例

package charactor;

public class GiantDragon {
	
	//*1 私有化构造方法
	private GiantDragon() {
		
	}
	
	//*2 准备一个类属性,指向一个实例化对象
	private static GiantDragon instance = new GiantDragon();
	
	//*3 公共静态方法 提供调用者获取内部实例的对象
	public static GiantDragon getInstance() {
		return instance;
	}
}

懒汉单例模式

懒汉式单例模式与饿汉式单例模式不同,只有在调用getInstance的时候,才会创建实例。

package charactor;

public class GiantDragon {

	//**1 私有化构造方法
	private GiantDragon() {
			
	}
	
	//**2 定义一个类属性,用于指向一个实例化对象,暂时指向null
	private static GiantDragon instance;
	
	//**3 公共静态(类)方法,用于返回实例对象
	public static GiantDragon getInstance() {
		
		//第一次访问,发现instance没有指向任何对象,此时进行初始化
		if (null == instance) {
			instance = new GiantDragon();
		}
		//返回instance指向的对象
		return instance;
	}
	
}	

饿汉和懒汉单例模式的调用方式

调用的方式都是相同的,并且生成的都是的单一对象。

package charactor;

public class TestGiantDragon {

	public static void main(String[] args) {
	
		//GiantGragon g = new GiantGragon();//不能直接用new创建对象
		
		//只能通过getInstance得到一个对象
		GiantDragon g1 = GiantDragon.getInstance();
		GiantDragon g2 = GiantDragon.getInstance();
		GiantDragon g3 = GiantDragon.getInstance();
		
		//都是同一个对象
		System.out.println(g1 == g2);//true
		System.out.println(g1 == g3);//true
		System.out.println(g2 == g3);//true
		
	}	
}

饿汉单例模式和懒汉单例模式的区别

饿汉式,是立即加载的方式,无论是否会用到这个对象,都会加载。
如果在构造方法里写了性能消耗较大,占时较久的代码,比如建立与数据库的连接,那么就会在启动的时候感觉稍微有些卡顿。

懒汉式,是延迟加载的方式,只有使用的时候才会加载。 并且有线程安全的考量。
使用懒汉式,在启动的时候,会感觉到比饿汉式略快,因为并没有做对象的实例化。 但是在第一次调用的时候,会进行实例化操作,感觉上就略慢。

看业务需求,如果业务上允许有比较充分的启动和初始化时间,就使用饿汉式,否则就使用懒汉式。

单例模式小练手

题目:

使用饿汉式单例模式, 把Hero类改造成为单例模式
使用懒汉式单例模式,把Item类改造成为单例模式

这里我们就不给Hero和Item里增加其他多余属性了。
老规矩,我们先自己写然后再对照答案。

这个是饿汉单例模式

package charactor;

public class SingleHero {

	//不用写主函数
		
	//饿汉汉单例模式
	//1. 构造方法私有化,无返回值
	private SingleHero() {
		
	}
		
	//2. 定义一个静态(类)属性指向实例,同时新建一个实例
	private static SingleHero instance = new SingleHero();
		
	//3. 定义一个公开静态(类)方法让外部可以调用,返回类型是类类型
	public static SingleHero getInstance() {
		return instance;
	}
	
	//4.使用方法是(不在本类里使用)
	//SingleHero s = SingleHero.getInstance();
			
}

这个是懒汉单例模式

package charactor;

public class SingleItem {

	//不用写主函数
	
	//懒汉单例模式
	//1. 私有化构造函数,无返回值
	private SingleItem() {
		
	}
	
	//2. 私有类属性指向实例对象,懒汉此时懒得不创建实例
	private static SingleItem instance;
	
	//3. 公共类 (静态)方法用来给外部调用创建实例,返回是类属性
	public static SingleItem getInstance() {
		//首次判断instance不存在则创建
		if (null == instance) {
			instance = new SingleItem();
		}
		//返回实例
		return instance;
	}
	
	//4.使用这个来创建实例,在其他class的main里
	//SingleItem s = SingleItem.getInstance();

}

你可能感兴趣的:(设计模式)