前言
设计模式代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。
一:单例模式
单例模式是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
步骤 1
创建一个 Singleton 类。
SingleObject.java
/**
* 创建一个 Singleton 类。
*/
public class SingleObject {
//创建 singletonpattern.SingleObject 的一个对象
private static SingleObject instane = new SingleObject();
//让构造函数为 private,这样该类就不会被实例化
private SingleObject() {
}
//获取唯一可用的对象
public static SingleObject getInstane() {
return instane;
}
//显示消息
public void showMessage() {
System.out.println("Hello World!");
}
}
步骤 2
从 singleton 类获取唯一的对象。
SingletonPatternDemo.java
/**
* 从 singleton 类获取唯一的对象。
*/
public class SingletonPatternDemo {
public static void main(String[] args) {
//不合法的构造函数
//编译时错误:构造函数 singletonpattern.SingleObject() 是不可见的
//singletonpattern.SingleObject object = new singletonpattern.SingleObject();
//获取唯一可用的对象
SingleObject object = SingleObject.getInstane();
object.showMessage();
}
}
步骤 3
验证输出。
Hello World!
二:单例模式的几种实现方式
1、懒汉式,线程不安全
/**
* 1、懒汉式,线程不安全
*/
public class Singleton1 {
private static Singleton1 instance;
private Singleton1() {
}
public static Singleton1 getInstance() {
if (instance == null) {
instance = new Singleton1();
}
return instance;
}
}
2、懒汉式,线程安全
/**
* 2、懒汉式,线程安全
* synchronized(同步)
*/
public class Singleton2 {
private static Singleton2 instance;
private Singleton2() {
}
public static synchronized Singleton2 getInstance() {
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}
3、饿汉式
public class Singleton3 {
private static Singleton3 instance = new Singleton3();
private Singleton3() {
}
public static Singleton3 getInstance() {
return instance;
}
}
4、双检锁/双重校验锁(DCL,即 double-checked locking)
public class Singleton4 {
private static Singleton4 instance;
private Singleton4() {
}
public static Singleton4 getInstance() {
if (instance == null) {
synchronized (Singleton4.class) {
if (instance == null) {
instance = new Singleton4();
}
}
}
return instance;
}
}
5、登记式/静态内部类
public class Singleton5 {
private static class SingletonHolder {
private static final Singleton5 INSTANCE = new Singleton5();
}
private Singleton5() {
}
public static final Singleton5 getInstance() {
return SingletonHolder.INSTANCE;
}
}
6、枚举
public enum Singleton6 {
INSTANCE;
public void whateverMethod() {
}
}
三:工厂模式
工厂模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
步骤 1
创建一个接口。
Shape.java
/**
* 接口
*/
public interface Shape {
void draw();
}
步骤 2
创建实现接口的实体类。
Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
Square.java
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
步骤 3
创建一个工厂,生成基于给定信息的实体类的对象。
ShapeFactory.java
/**
* 创建一个工厂,生成基于给定信息的实体类的对象。
*/
public class ShapeFactory {
//使用 getShape 方法获取形状类型的对象
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
步骤 4
使用该工厂,通过传递类型信息来获取实体类的对象。
FactoryPatternDemo.java
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//获取 Circle 的对象,并调用它的 draw 方法
Shape shape1 = shapeFactory.getShape("CIRCLE");
//调用 Circle 的 draw 方法
shape1.draw();
//获取 Rectangle 的对象,并调用它的 draw 方法
Shape shape2 = shapeFactory.getShape("RECTANGLE");
//调用 Rectangle 的 draw 方法
shape2.draw();
//获取 Square 的对象,并调用它的 draw 方法
Shape shape3 = shapeFactory.getShape("SQUARE");
//调用 Square 的 draw 方法
shape3.draw();
}
}
步骤 5
验证输出。
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Demo地址
最后
不懂得地方欢迎私信我,我会在第一时间给予回复,如阅读中发现写错的地方,欢迎纠正。