使用private构造器 or 枚举的原生语言实现单例

简介: 相信接触过设计模式的同学都知道,单例的一种经典实现方式就是private的构造函数,但直到我看到这一章节内容的时候,才突然顿悟原来枚举类型也是可以强化单例属性的,自愧个人的融会贯通能力还有待加强。

相信接触过设计模式的同学都知道,单例的一种经典实现方式就是private的构造函数,但直到我看到这一章节内容的时候,才突然顿悟原来枚举类型也是可以强化单例属性的,自愧个人的融会贯通能力还有待加强。

实现单例方式一:


// Singleton with public final field
public class Elvis {
  public static final Elvis INSTANCE= new Elvis();
  private Elvis() { .. . }
}


这种实现方式有一个缺点就是可以借助反射机制里的AccessibleObject.setAccessible来强制修改构造函数成为public的

实现单例方式二:


// Singleton with static factory
public class Elvis {
private static final Elvis INSTANζE = new Elvis();
  private Elvis() { ... }
  public static Elvis getInstance() {return INSTANCE; }
}


在实际抉择中,如果用到了以下某种优势,则优先考虑第二种实现,否则考虑第一种单例实现:


可以很容易被修改成非单例的(修改getInstance的返回语句即可)

可以使用Elvis::instance语法


此外,为了防止每次序列化和反序列化都创建一个新实例而破坏了单例特性,需要在Elvis类中添加一个方法:


private Object readResolve () {
  return INSTANCE;
}


实现单例方式三:


这种方式也是我原先没有想到的,声明包含单个元素的枚举类型来实现:

public enum Elvis {
  INSTANCE;
  public void leaveTheBuilding() { .. . }
}


其中Elvis.INSTANCE可以获得单例,Elvis.INSTANCE.leaveTheBuilding();调方法。


这种方式也是作者极力推荐的一种方式,无偿地提供了序列化机制,绝对防止多次实例化。单元素的枚举类型经常成为实现Singleton的最佳方法。

相关文章
|
8月前
|
设计模式 JavaScript 前端开发
在JavaScript中,继承是一个重要的概念,它允许我们基于现有的类(或构造函数)创建新的类
【6月更文挑战第15天】JavaScript继承促进代码复用与扩展,创建类层次结构,但过深的继承链导致复杂性增加,紧密耦合增加维护成本,单继承限制灵活性,方法覆盖可能隐藏父类功能,且可能影响性能。设计时需谨慎权衡并考虑使用组合等替代方案。
52 7
|
5月前
|
Java PHP 数据安全/隐私保护
PHP 面向对象,构造函数,析构函数,继承,方法的重写,接口抽象类,static,final,this,parent,self的异同和作用
本文详细介绍了PHP面向对象编程的一系列核心概念和用法,包括构造函数、析构函数、继承、方法重写、访问控制、接口、抽象类、静态成员、final关键字、以及this、self、parent这三个关键字的异同和作用。通过具体示例代码,展示了如何在PHP中使用这些面向对象的特性,以及它们在实际开发中的应用。
PHP 面向对象,构造函数,析构函数,继承,方法的重写,接口抽象类,static,final,this,parent,self的异同和作用
|
8月前
|
Java 编译器
在 Java 中,重写(Override)和重载(Overload)是两种不同的概念,用于实现多态性。它们有着不同的作用和使用场景。
在 Java 中,重写(Override)和重载(Overload)是两种不同的概念,用于实现多态性。它们有着不同的作用和使用场景。
|
8月前
|
Java
java反射-获取类的Class对象方式
java反射-获取类的Class对象方式
|
9月前
|
Java
Java提供了四种访问修饰符来控制类、变量、方法和构造器的访问级别
Java提供了四种访问修饰符来控制类、变量、方法和构造器的访问级别
72 1
泛型-使用泛型结合工厂方法实现单例模式,以支持类型自定义
泛型-使用泛型结合工厂方法实现单例模式,以支持类型自定义
|
druid Java 编译器
Java的第七篇文章——面向对象接口(包含了接口、static修饰符、final修饰符、main方法、内部类等知识点)
Java的第七篇文章——面向对象接口(包含了接口、static修饰符、final修饰符、main方法、内部类等知识点)
|
SQL 缓存 安全
Java枚举单例模式比DCL和静态单例要好?———反编译分析单例枚举类
枚举单例模式比DCL和静态单例模式要好?为什么好呢?本文带你一探究竟!
123 0
Java枚举单例模式比DCL和静态单例要好?———反编译分析单例枚举类
|
Java 编译器 数据库
Java维护常量方式的比较——接口、常量类与枚举
Java维护常量方式的比较——接口、常量类与枚举 一、示例 ​ 1.让类实现定义了常量的接口
|
缓存 Dart 安全
Dart中的类——初始化列表、命名构造器、factory构造器、常量构造器、构造器私有化、get和set方法、枚举
Dart中的类——初始化列表、命名构造器、factory构造器、常量构造器、构造器私有化、get和set方法、枚举