Java设计模式详解
设计模式是软件开发过程中针对常见问题的经过验证的、可复用的解决方案。Java作为一种面向对象的编程语言,广泛应用各种设计模式。以下详细介绍Java中常见的23种设计模式,分为创建型、结构型和行为型三大类。
创建型模式
创建型模式关注对象的创建过程,试图将对象的创建与使用分离。
1. 单例模式 (Singleton Pattern)
定义:确保一个类只有一个实例,并提供一个全局访问点。
实现方式:
- 饿汉式:类加载时就创建实例
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
- 懒汉式:延迟创建实例(线程不安全)
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
- 双重检查锁定:线程安全且高效
public class DCLSingleton {
private volatile static DCLSingleton instance;
private DCLSingleton() {}
public static DCLSingleton getInstance() {
if (instance == null) {
synchronized (DCLSingleton.class) {
if (instance == null) {
instance = new DCLSingleton();
}
}
}
return instance;
}
}
- 静态内部类:线程安全且延迟加载
public class StaticInnerSingleton {
private StaticInnerSingleton() {}
private static class SingletonHolder {
private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();
}
public static StaticInnerSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 枚举:最简洁的实现,自动处理序列化
public enum EnumSingleton {
INSTANCE;
public void doSomething() {
// 业务方法
}
}
应用场景:
- 配置管理器
- 线程池、连接池
- 缓存
- 日志记录器
Java中的应用:
java.lang.Runtime
java.awt.Desktop
2. 工厂方法模式 (Factory Method Pattern)
定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
结构:
- 抽象产品
- 具体产品
- 抽象工厂
- 具体工厂
示例:
// 抽象产品
interface Product {
void operation();
}
// 具体产品
class ConcreteProductA implements Product {
@Override
public void operation() {
System.out.println("ConcreteProductA operation");
}
}
class ConcreteProductB implements Product {
@Override
public void operation() {
System.out.println("ConcreteProductB operation");
}
}
// 抽象工厂
abstract class Creator {
public abstract Product createProduct();
public void someOperation() {
Product product = createProduct();
product.operation();
}
}
// 具体工厂
class ConcreteCreatorA extends Creator {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
class ConcreteCreatorB extends Creator {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
应用场景:
- 当一个类不知道它所需要的对象的类时
- 当一个类希望由子类来指定它所创建的对象时
- 当类将创建对象的职责委托给多个帮助子类中的某一个时
Java中的应用:
java.util.Calendar.getInstance()
java.util.ResourceBundle.getBundle()
java.text.NumberFormat.getInstance()
3. 抽象工厂模式 (Abstract Factory Pattern)
定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
结构:
- 抽象产品族
- 具体产品
- 抽象工厂
- 具体工厂
示例:
// 抽象产品A
interface ProductA {
void operationA();
}
// 具体产品A1
class ConcreteProductA1 implements ProductA {
@Override
public void operationA() {
System.out.println("ProductA1 operationA");
}
}
// 具体产品A2
class ConcreteProductA2 implements ProductA {
@Override
public void operationA() {
System.out.println("ProductA2 operationA");
}
}
// 抽象产品B
interface ProductB {
void operationB();
}
// 具体产品B1
class ConcreteProductB1 implements ProductB {
@Override
public void operationB() {
System.out.println("ProductB1 operationB");
}
}
// 具体产品B2
class ConcreteProductB2 implements ProductB {
@Override
public void operationB() {
System.out.println("ProductB2 operationB");
}
}
// 抽象工厂
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
应用场景:
- 系统需要独立于产品的创建、组合和表示
- 系统需要由多个产品系列中的一个来配置
- 强调一系列相关产品对象的设计以便进行联合使用
Java中的应用:
javax.xml.parsers.DocumentBuilderFactory
javax.xml.transform.TransformerFactory
- Spring中的BeanFactory
4. 建造者模式 (Builder Pattern)
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
结构:
- 产品
- 抽象建造者
- 具体建造者
- 指挥者
示例:
// 产品
class Product {
private String partA;
private String partB;
private String partC;
public void setPartA(String partA) {
this.partA = partA;
}
public void setPartB(String partB) {
this.partB = partB;
}
public void setPartC(String partC) {
this.partC = partC;
}
@Override
public String toString() {
return "Product{partA='" + partA + "', partB='" + partB + "', partC='" + partC + "'}";
}
}
// 抽象建造者
interface Builder {
void buildPartA();
void buildPartB();
void buildPartC();
Product getResult();
}
// 具体建造者
class ConcreteBuilder implements Builder {
private Product product = new Product();
@Override
public void buildPartA() {
product.setPartA("PartA");
}
@Override
public void buildPartB() {
product.setPartB("PartB");
}
@Override
public void buildPartC() {
product.setPartC("PartC");
}
@Override
public Product getResult() {
return product;
}
}
// 指挥者
class Director {
public Product construct(Builder builder) {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}
}
应用场景:
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时
- 当构造过程必须允许被构造的对象有不同的表示时
Java中的应用:
java.lang.StringBuilder
java.lang.StringBuffer
- Lombok的
@Builder
注解 - Spring的
BeanDefinitionBuilder
现代Java中的实现: 流式接口(链式调用)
public class Person {
private final String name;
private final int age;
private final String address;
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.address = builder.address;
}
public static class Builder {
private String name;