创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成。就像我们去商场购买商品时,不需要知道商品是怎么生产出来一样,因为它们由专门的厂商生产。
创建型模式分为以下几种:
- 单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。
- 原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
- 工厂方法(FactoryMethod)模式:定义一个用于创建产品的接口,由子类决定生产什么产品。(类创建型模式)
- 抽象工厂(AbstractFactory)模式:提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。
- 建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。
除了工厂方法是类创建型模式,其他的都是对象创建型模式。
单例模式(Singleton)
单例模式有 3 个特点:
-
单例类只有一个实例对象;
- 该单例对象必须由单例类自行创建;
- 单例类对外提供一个访问该单例的全局访问点;
好处:
- 某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
- 省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
- 有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
实现方式 :
1、懒汉式单例:类加载时没有生成单例,只有当第一次调用 getlnstance 方法时才去创建这个单例
2、饿汉式单例:类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。
3、双检锁/双重校验锁(DCL,即 double-checked locking)
4、登记式/静态内部类
扫描二维码关注公众号,回复:
8986108 查看本文章
具体实现 :
1、非线程安全的懒汉式单例
/**
* @description 线程不安全 的懒汉式
* @date 2019/7/26
*/
public class UnsafeLazySingleton {
private static UnsafeLazySingleton instance;
private UnsafeLazySingleton (){}
public static UnsafeLazySingleton getInstance() {
if (instance == null) {
instance = new UnsafeLazySingleton();
}
return instance;
}
}
2、线程安全的懒汉式单例
/**
* @description 线程安全的懒汉式单例
* @date 2019/7/26
*/
public class SafeLazySingleton {
private static SafeLazySingleton instance;
private SafeLazySingleton (){}
public static synchronized SafeLazySingleton getInstance() {
if (instance == null) {
instance = new SafeLazySingleton();
}
return instance;
}
}
3、饿汉式
多线程安全 ,它基于 classloader 机制避免了多线程的同步问题。
/**
* @description 饿汉式实例
* @date 2019/7/26
*/
public class HungrySingleton {
//多线程安全 ,它基于 classloader 机制避免了多线程的同步问题
private static final HungrySingleton instance=new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance()
{
return instance;
}
}
4、双重校验锁
多线程安全 、懒汉式
/**
* @description 双检锁/双重校验锁
* @date 2019/7/26
*/
public class DCLSingleton {
private volatile static DCLSingleton singleton;
private DCLSingleton (){}
public static DCLSingleton getSingleton() {
if (singleton == null) {
synchronized (DCLSingleton.class) {
if (singleton == null) {
singleton = new DCLSingleton();
}
}
}
return singleton;
}
}
5、登记式/静态内部类
线程安全 、懒汉式加载
利用了 classloader 机制来保证初始化 instance 时只有一个线程, SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance。
/**
* @description 静态内部类实现
* @date 2019/7/26
*/
public class StaticInnerSingleton {
private static class SingletonHolder {
private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();
}
private StaticInnerSingleton (){}
public static final StaticInnerSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
6、枚举的方式
涉及到反序列化创建对象时可使用 。
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
参考 : https://www.runoob.com/design-pattern/singleton-pattern.html