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

前言

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

最后

不懂的地方可以私信我,我会及时给予回复。若在阅读中发现写错的地方,欢迎进行纠正。

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

26阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

28阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

26阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

26阅读