主要解决对象的创建问题
定义:一个类只允许创建一个实例 使用场景:处理资源访问冲突;数据在系统种只应该保存一份(如配置信息) 实现方式:主要考虑以下3个方面:构造函数private,创建对象线程安全,是否延迟加载
存在的问题:
单例对OOP特性支持不友好:封装/继承/多态/抽象 单例会隐藏类之间的依赖关系:类似于工具类一样使用时属于硬编码,不便查找 单例对代码的扩展性不友好 单例对代码的可测试性不友好:由于类似硬编码,不方便mock 单例不支持有参数的构造函数
单例的替代方式:工厂模式,ioc容器
单例的作用范围:
进程内唯一(大多数情况) 线程内唯一(用类似ThreadLocal的Map即可实现) 多进程内唯一(分布式),用一个集中式的共享区域存储,如db数据库等
/**
* 单例:饥饿模式——类加载时就创建对象
* 过早占用内存,存在性能问题?
* 若初始化耗时,应该在应用启动时就初始化好,避免使用时再创建出现性能问题
* 占用内存多?按照fail-fast设计原则(有问题及早暴漏),启动时就能检查内存是否够用
*/
public final class EagerSingleton {
/**
* 类加载的时候执行clinit()时将创建对象,线程安全
*/
private static final EagerSingleton INSTANCE = new EagerSingleton();
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
return INSTANCE;
}
}
/**
* 单例:懒汉模式——延迟加载
* 同步范围过大(锁对象为类Class对象),性能不佳
*/
public final class LazySingleton {
private static LazySingleton INSTANCE;
private LazySingleton() {
}
public synchronized static LazySingleton getInstance() {
if (INSTANCE != null) {
INSTANCE = new LazySingleton();
}
return INSTANCE;
}
}
/**
* 单例:双重检测
*
* 初始化对象的3个步骤:
* 1)分配内存空间
* 2)初始化对象
* 3)将内存空间的地址赋值给对应的引用
* 由于虚拟机有指令重排优化机制,上述步骤可能会变为 1-3-2,所以需要 volatile 关键字来保证禁止重排指令,
* 如果以1-3-2顺序执行,线程A运行到第2次检查通过后正在初始化对象,初始化对象需要一定时间,这时步骤已完成1和3,
* 线程B运行到第1次检查发现不为null,则直接返回,实际上 线程A还没有完成初始化对象的步骤2,造成了jvm异常
*/
public final class DoubleCheckedSingleton {
private volatile static DoubleCheckedSingleton INSTANCE;
private DoubleCheckedSingleton() {
}
public static DoubleCheckedSingleton getInstance() {
//第1次检查
if (INSTANCE == null) {
synchronized (DoubleCheckedSingleton.class) {
//第2次检查
if (INSTANCE == null) {
INSTANCE = new DoubleCheckedSingleton();
}
}
}
return INSTANCE;
}
}
/**
* 单例:内部类-懒加载
*/
public final class InnerClassSingleton {
private InnerClassSingleton() {
}
private static class SingletonHolder {
public static final InnerClassSingleton INSTANCE = new InnerClassSingleton();
}
public static InnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
/**
* 单例:枚举
*/
public enum EnumSingleton {
INSTANCE
}
特殊的单例,一个类允许有固定的多个实例,区别于工厂模式,多例是同一个类型的多个实例,而工厂模式是多个不同子类的实例
实现方式:枚举 或 使用map结构
/**
* 多例:枚举
*/
public enum EnumMultiton {
INSTANCE1,
INSTANCE2,
INSTANCE3
}
/**
* 多例:双重检测
*/
public final class DoubleCheckedMultiton {
private static final Map<String, DoubleCheckedMultiton> INSTANCE_BY_NAME = new HashMap<>();
private DoubleCheckedMultiton() {
}
public static DoubleCheckedMultiton getInstance(String name) {
DoubleCheckedMultiton INSTANCE = INSTANCE_BY_NAME.get(name);
//第1次检查
if (INSTANCE == null) {
synchronized (DoubleCheckedMultiton.class) {
//第2次检查
if (INSTANCE == null) {
INSTANCE = new DoubleCheckedMultiton();
INSTANCE_BY_NAME.put(name, INSTANCE);
}
}
}
return INSTANCE;
}
}
用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象
工厂类直接创建对象,static方法,最简单
/**
* 简单工厂模式
*/
public class Factory {
private static final Map<String, IObject> OBJECT_BY_TYPE = new HashMap<>();
static {
OBJECT_BY_TYPE.put("A", new ObjectA());
OBJECT_BY_TYPE.put("B", new ObjectB());
OBJECT_BY_TYPE.put("C", new ObjectC());
}
public static IObject createObject(String type) {
if (type == null || type.isEmpty()) {
return null;
}
return OBJECT_BY_TYPE.get(type.toUpperCase());
}
}
public interface IObject {
}
public class ObjectA implements IObject {
}
public class ObjectB implements IObject {
}
public class ObjectC implements IObject {
}
将创建对象的行为下沉到各个类型自己的工厂类中,这些类型工厂类实现一个工厂接口,和工厂接口一起再使用一个简单工厂模式对外暴漏
/**
* 工厂方法模式
*/
public class Factory {
private static final Map<String, ObjectFactory> FACTORY_BY_TYPE = new HashMap<>();
static {
FACTORY_BY_TYPE.put("A", new ObjectAFactory());
FACTORY_BY_TYPE.put("B", new ObjectBFactory());
FACTORY_BY_TYPE.put("C", new ObjectCFactory());
}
public static ObjectFactory createObject(String type) {
if (type == null || type.isEmpty()) {
return null;
}
return FACTORY_BY_TYPE.get(type.toUpperCase());
}
}
public interface IObject {
}
public interface ObjectFactory {
IObject createObject(String type);
}
public class ObjectAFactory implements ObjectFactory {
@Override
public IObject createObject(String type) {
//复杂的创建逻辑
return new ObjectA();
}
}
public class ObjectBFactory implements ObjectFactory {
@Override
public IObject createObject(String type) {
//复杂的创建逻辑
return new ObjectB();
}
}
public class ObjectCFactory implements ObjectFactory {
@Override
public IObject createObject(String type) {
//复杂的创建逻辑
return new ObjectC();
}
}
public class ObjectA implements IObject {
}
public class ObjectB implements IObject {
}
public class ObjectC implements IObject {
}
不常用,相当于原来的实例可以通过两个维度去划分,在工厂方法的基础上,每个维度创建实例都在工厂方法中有对应的方法
/**
* 抽象工厂模式
*/
public class Factory {
private static final Map<String, ObjectFactory> FACTORY_BY_TYPE = new HashMap<>();
static {
FACTORY_BY_TYPE.put("A", new ObjectAFactory());
FACTORY_BY_TYPE.put("B", new ObjectBFactory());
FACTORY_BY_TYPE.put("C", new ObjectCFactory());
}
public static ObjectFactory createObject(String type) {
if (type == null || type.isEmpty()) {
return null;
}
return FACTORY_BY_TYPE.get(type.toUpperCase());
}
}
public interface IObject {
}
public interface IObjectA extends IObject {
}
public interface IObjectB extends IObject {
}
public interface IObjectC extends IObject {
}
public interface ObjectFactory {
IObject createObject1(String type);
IObject createObject2(String type);
}
public class ObjectA1 implements IObjectA {
}
public class ObjectA2 implements IObjectA {
}
public class ObjectB1 implements IObjectB {
}
public class ObjectB2 implements IObjectB {
}
public class ObjectC1 implements IObjectC {
}
public class ObjectC2 implements IObjectC {
}
public class ObjectAFactory implements ObjectFactory {
@Override
public IObject createObject1(String type) {
//复杂的创建逻辑
return new ObjectA1();
}
@Override
public IObject createObject2(String type) {
return new ObjectA2();
}
}
public class ObjectBFactory implements ObjectFactory {
@Override
public IObject createObject1(String type) {
//复杂的创建逻辑
return new ObjectB1();
}
@Override
public IObject createObject2(String type) {
//复杂的创建逻辑
return new ObjectB2();
}
}
public class ObjectCFactory implements ObjectFactory {
@Override
public IObject createObject1(String type) {
//复杂的创建逻辑
return new ObjectC1();
}
@Override
public IObject createObject2(String type) {
//复杂的创建逻辑
return new ObjectC2();
}
}
用来创建一种类型的复杂对象,通过设置不同的可选参数,”定制化”地创建不同的对象 对象一旦创建就不允许修改
/**
* 建造者模式
*/
public class ObjectPool {
private int fieldA;
private String fieldB;
private ObjectPool(Builder builder) {
this.fieldA = builder.fieldA;
this.fieldB = builder.fieldB;
}
public static class Builder {
private int fieldA;
private String fieldB;
public ObjectPool build() {
//创建ObjectPool逻辑处理
if (fieldA < 0) {
throw new IllegalArgumentException("...");
}
if (fieldB == null || fieldB.isEmpty()) {
throw new IllegalArgumentException("...");
}
return new ObjectPool(this);
}
public Builder setFieldA(int fieldA) {
if (fieldA < 0) {
throw new IllegalArgumentException("...");
}
this.fieldA = fieldA;
return this;
}
public Builder setFieldB(String fieldB) {
if (fieldB == null || fieldB.isEmpty()) {
throw new IllegalArgumentException("...");
}
this.fieldB = fieldB;
return this;
}
}
}
对象的创建成本较大,直接根据已有对象复制一个新的对象的方式 深拷贝(Deep Copy)和浅拷贝(Shallow Copy)
/**
* 原型模式
*/
public class ProtoType {
/**
* 深拷贝,浅拷贝
* 原型模式使用深拷贝,一般使用序列化相对简单,jdk原生序列化,json序列化,kryo序列化。。。
*/
}