Java设计模式最佳实践:单例模式详解与实现步骤
前言

设计模式代表着最优的实践,通常被经验丰富的面向对象的软件开发人员所运用。它是软件开发人员在软件开发进程中所遇到的普遍问题的解决办法。
一:单例模式
单例模式在 Java 中属于较为简单的设计模式。此类设计模式属于创建型模式,它为创建对象提供了一种最优方式。
这种模式包含一个单一的类,这个类有创建自身对象的职责,并且能保证只创建出一个对象。该类提供了一种获取其唯一对象的途径,能够直接进行访问,无需对该类的对象进行实例化。
单例类有这样的特点:其一,单例类只能存在一个实例;其二,单例类必须由自身来创建唯一的那个实例;其三,单例类必须向所有其他对象提供这一实例。
步骤 1
创建一个 Singleton 类。
SingleObject.java
/**
* 创建一个 Singleton 类。
*/
public class SingleObject {
创建一个 singletonpattern.SingleObject 的对象
创建了一个名为 instane 的静态 SingleObject 对象,该对象是通过 new SingleObject() 语句初始化的,并且是私有的。
//让构造函数为 private,这样该类就不会被实例化
private SingleObject() {
}
//获取唯一可用的对象
获取静态的 SingleObject 实例。
return instane;
}
//显示消息
public void showMessage() {
在控制台输出 "Hello World!" 。
}
}
步骤 2
从 singleton 类获取唯一的对象。
SingletonPatternDemo.java
/**
* 从 singleton 类获取唯一的对象。
*/
它在代码中有着重要的作用和意义。
主函数的定义方式为 public static void main,参数为 String[] args。
//不合法的构造函数
编译时出现错误,构造函数 singletonpattern.SingleObject() 是不可见的。
创建了 singletonpattern 包中的 SingleObject 类的对象 object,即 singletonpattern.SingleObject object = new singletonpattern.SingleObject();
//获取唯一可用的对象
SingleObject 这个对象是通过 SingleObject.getInstane()方法获取到的。
object.showMessage();
}
}
步骤 3
验证输出。
Hello World!
二:单例模式的几种实现方式1、懒汉式,线程不安全
/**
* 1、懒汉式,线程不安全
*/
public class Singleton1 {
静态的 Singleton1 实例是私有的。
private Singleton1() {
}
静态的 Singleton1 获取实例的方法是:如果单例实例为空,则创建一个新的单例实例并返回;如果单例实例已存在,则直接返回已存在的单例实例。
if (instance == null) {
instance = new Singleton1();
}
return instance;
}
}
2、懒汉式,线程安全
/**
* 2、懒汉式,线程安全
* synchronized(同步)
*/
public class Singleton2 {
静态的 Singleton2 实例为 instance 。
private Singleton2() {
}
这样可以保证在多线程环境下,获取 Singleton2 的实例是线程安全的,即不会同时创建多个 Singleton2 的实例。
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}
3、饿汉式
public class Singleton3 {
Singleton3 的实例 instance 是通过 new Singleton3() 创建的,且是私有的静态实例。
private Singleton3() {
}
如果 Singleton3 尚未实例化,那么将创建一个新的 Singleton3 实例。如果 Singleton3 已经实例化,那么直接返回已存在的实例。最终返回 Singleton3 的实例。
return instance;
}
}
双检锁,也就是双重校验锁(DCL)。
public class Singleton4 {
静态的 Singleton4 实例为 instance 。
private Singleton4() {
}
获取实例的方式是通过调用 public static Singleton4 getInstance() 这个方法。
if (instance == null) {
对 Singleton4.class 进行同步操作,即通过同步锁来确保同一时刻只有一个线程能够访问这段代码块。
if (instance == null) {
instance = new Singleton4();
}
}
}
return instance;
}
}
5、登记式/静态内部类
public class Singleton5 {
静态内部类 SingletonHolder 中,包含了单例对象的实例。在该内部类中,定义了一个私有的静态成员变量 instance,用于存储单例对象的实例。当首次调用 getInstance 方法时,会触发 SingletonHolder 的初始化过程,从而创建单例对象的实例,并将其存储在 instance 变量中。之后,每次调用 getInstance 方法时,都会直接返回已经创建好的单例对象的实例,而不会再次创建新的对象。这样就实现了单例模式的延迟加载和线程安全。
Singleton5 的私有静态常量 INSTANCE 被初始化为一个新的 Singleton5 对象。
}
private Singleton5() {
}
- 公共的、静态的且最终的 Singleton5 去获取实例。
返回 SingletonHolder 的 INSTANCE 。
}
}
6、枚举
public enum Singleton6 {
INSTANCE;
这个方法的主要作用是进行一些特定的操作,具体来说:它会先执行一些初始化的步骤,然后对相关的数据进行处理,接着可能会进行一些判断和决策,最后根据不同的情况执行相应的后续操作。整个过程是按照一定的逻辑顺序依次进行的,以实现特定的功能。
}
}
三:工厂模式
工厂模式在 Java 中是较为常用的设计模式之一。此类设计模式属于创建型模式,它为创建对象提供了一种最优的方式。
在工厂模式里,我们在创建对象的时候不会让客户端知晓创建逻辑。并且是借助一个共同的接口来指向新创建出来的对象。
步骤 1
创建一个接口。
Shape.java
/**
* 接口
*/
public interface Shape {
void draw();
}
步骤 2
创建实现接口的实体类。
Rectangle.java
类 Rectangle 实现了 Shape 接口。
@Override
public void draw() {
System.out 进行了 "Inside Rectangle::draw() method." 的输出。
}
}
Square.java
公共类 Square 实现了 Shape 接口。
@Override
public void draw() {
"Inside Square::draw() method." 被 System 输出了。
}
}
Circle.java
类 Circle 实现了 Shape 接口。
@Override
public void draw() {
在 Circle 的 draw() 方法内部。
}
}
步骤 3
创建一个工厂,生成基于给定信息的实体类的对象。
ShapeFactory.java
/**
* 创建一个工厂,生成基于给定信息的实体类的对象。
*/
public class ShapeFactory {
//使用 getShape 方法获取形状类型的对象
如果 shapeType 是 "Circle",则返回一个新的 Circle 对象;如果 shapeType 是 "Rectangle",则返回一个新的 Rectangle 对象;如果 shapeType 是 "Triangle",则返回一个新的 Triangle 对象。
if(shapeType == null){
return null;
}
如果 shapeType 不区分大小写等于 "CIRCLE",那么就执行以下操作。
return new Circle();
如果 shapeType 不区分大小写等于 "RECTANGLE",那么就执行以下操作。
return new Rectangle();
如果 shapeType 不区分大小写地等于 "SQUARE",那么就执行以下操作;如果 shapeType 不区分大小写地等于 "SQUARE",则进行后续处理;若 shapeType 不区分大小写地为 "SQUARE",就开展相应步骤;要是 shapeType 不区分大小写地是 "SQUARE",便执行相关事宜;当 shapeType 不区分大小写地等同于 "SQUARE" 时,就做相应的事。
return new Square();
}
return null;
}
}
步骤 4
使用该工厂,通过传递类型信息来获取实体类的对象。
FactoryPatternDemo.java
公共类 FactoryPatternDemo ,在这个类中进行相关操作和代码编写,用于展示工厂模式的示例和效果。它包含了创建对象的相关逻辑和方法,通过工厂类来创建不同类型的对象,而不是直接在客户端代码中实例化对象,这样可以提高代码的可维护性和扩展性。
公共静态的 void 方法 main,它的参数是 String 类型的数组 args。
创建了一个 ShapeFactory 的实例,名为 shapeFactory 。
//获取 Circle 的对象,并调用它的 draw 方法
Shape shape1 是由 shapeFactory 获取到的形状,其形状类型为“CIRCLE”。
//调用 Circle 的 draw 方法
shape1.draw();
获取 Rectangle 的对象,然后调用该对象的 draw 方法。
//调用 Rectangle 的 draw 方法
shape2.draw();
//获取 Square 的对象,并调用它的 draw 方法
//调用 Square 的 draw 方法
shape3.draw();
}
}
步骤 5
验证输出。
Inside Circle::draw() method.
在 Rectangle 的 draw() 方法内部。
Inside Square::draw() method.
Demo地址
IT人生的Github地址:Demo
最后
不懂的地方可以私信我,我会及时给予回复。若在阅读中发现写错的地方,欢迎进行纠正。