设计模式概述
设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案(也就是现成的套路)
分类:创建型模式、结构型模式、行为型模式
设计模式是基于场景的解决方案
单例模式的定义和作用
目的: 使得类的一个对象成为该类系统中的唯一实例
定义: 一个类有且仅有一个实例,并且自行实例化向整个系统提供
要点:
1.某个类只能有一个实例
2.必须自行创建实例
3.必须自行向整个系统提供这个实例
实现:
1.只提供私有的构造方法
2.含有一个该类的静态私有对象
3.提供一个静态的公有方法用于创建、获取静态私有对象
代码实现方案:饿汉式(对象创建过程中实例化)、懒汉式(静态公有方法中实例化)
饿汉式代码实现
实例化对象的类
package com.imooc.singleton;
//饿汉式:创建对象实例的时候直接初始化 空间换时间
public class SingletonOne {
//1.创建类中私有构造
private SingletonOne() {
}
//2.创建该类型的私有静态实例
private static SingletonOne instance = new SingletonOne();
//3。创建公有静态方法返回静态实例对象
public static SingletonOne getInstance() {
return instance;
}
}
测试类
package com.imooc.test;
import com.imooc.singleton.SingletonOne;
public class Test {
public static void main(String[] args) {
SingletonOne one = SingletonOne.getInstance();
SingletonOne two = SingletonOne.getInstance();
System.out.println(one);
System.out.println(two);
}
}
运行输出结果
com.imooc.singleton.SingletonOne@35f983a6
com.imooc.singleton.SingletonOne@35f983a6
通过这个输出结果我们可以看到对象one和two都是指向的同一块区域,这就是单例模式的效果
饿汉式运行时间快但是空间耗费大。
懒汉式代码实现
实例化对象的类
package com.imooc.singleton;
//懒汉式:类内实例对象创建时并不直接初始化,直到第一次调用get方法时才完成初始化
//时间换空间
public class SingletonTwo {
//1.创建私有构造方法
private SingletonTwo() {
}
//2.创建静态的该类实例对象
private static SingletonTwo instance = null;
//3.创建开放静态方法提供实例对象
public static SingletonTwo getInstance() {
if (instance == null) {
instance = new SingletonTwo();
}
return instance;
}
}
测试类
package com.imooc.test;
import com.imooc.singleton.SingletonTwo;
public class Test {
public static void main(String[] args) {
System.out.println("=====================");
SingletonTwo one1 = SingletonTwo.getInstance();
SingletonTwo two1 = SingletonTwo.getInstance();
System.out.println(one1);
System.out.println(two1);
}
}
运行输出的结果
com.imooc.singleton.SingletonTwo@edf4efb
com.imooc.singleton.SingletonTwo@edf4efb
可以看到两个对象指向的是同一块区域,说明这个代码是正确的
懒汉式运行较慢但空间耗费小
饿汉式pk懒汉式
饿汉式: 在类加载时就创建实例。时间快,空间耗费大
懒汉式: 第一次使用时进行实例化。时间慢,空间耗费小
多线程时饿汉式线程安全,懒汉式存在线程风险
单例模式的特点及适用场景
优点:
1.在内存中只有一个对象,节省内存空间
2.避免频繁的创建销毁对象,提高性能
3.避免对共享资源的多重占用
缺点:
1.扩展比较困难
2.如果实例化后的对象长期不利用,系统将默认为垃圾进行回收,造成对象状态丢失
使用场景:
1.创建对象时占用资源过多,但同时又要用到该类对象
2.对系统内资源要求统一读写,如读写配置信息
3.当多个实例存在可能引起程序逻辑错误,如号码生成器