Java 中的 23 种设计模式详解

#VibeCoding·九月创作之星挑战赛#

Java中的23种设计模式


设计模式是软件开发中的最佳实践,帮助开发者在面对复杂设计问题时提供有效的解决方案。GoF(Gang of Four)在其经典著作《设计模式:可复用面向对象软件的基础》中定义了 23 种设计模式。。本文将详细介绍23种经典设计模式,包括创建型模式、结构型模式和行为型模式,提供每种模式的定义、原理、优点、Java示例代码以及详细注释。

一、创建型模式(Creational Patterns)

创建型模式关注于对象的创建,提供了更灵活的对象创建方式。

1.1 单例模式(Singleton Pattern)

核心思想:确保一个类只有一个实例,并提供一个全局访问点。
实现方式:通过私有化构造函数和提供一个静态方法来获取实例。
应用场景:数据库连接池、配置管理类、日志记录器。

优点

  • 控制实例数量:保证只有一个实例。
  • 提供全局访问点:方便在全局范围内访问该实例。

Java 示例

public class Singleton {
    // 类加载时不创建实例
    private static volatile Singleton instance;

    // 私有构造函数,防止外部实例化
    private Singleton() {}

    // 提供全局访问点,使用双重检查锁定机制保证线程安全
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

双重检查(Double-Check) 概念对于多线程开发者来说不会陌生,进行了两次if (instance == null)检查,这样就可以保证线程安全。实例化代码只需执行一次,后面再次访问时,判断if (instance == null),直接return实例化对象。

更多拓展:Java 设计模式之单例模式

1.2 原型模式(Prototype Pattern)

核心思想:通过复制现有的实例来创建新实例,而不是通过构造函数。
实现方式:实现 Cloneable 接口并重写 clone() 方法来复制对象。
应用场景:游戏角色复制、避免重复初始化开销。

优点

  • 减少创建新对象的开销:通过复制现有对象创建新对象。
  • 动态配置对象:可以在运行时配置对象状态。

Java 示例

// 原型接口
public interface Prototype extends Cloneable {
    Prototype clone();
}

// 具体原型类
public class ConcretePrototype implements Prototype {
    private String data;

    public ConcretePrototype(String data) {
        this.data = data;
    }

    // 使用浅拷贝
    @Override
    public Prototype clone() {
        try {
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            // 处理克隆不支持异常
            return null;
        }
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ConcretePrototype prototype = new ConcretePrototype("Prototype Data");
        ConcretePrototype clonedPrototype = (ConcretePrototype) prototype.clone();
        System.out.println(clonedPrototype.getData()); // 输出: Prototype Data
        clonedPrototype.setData("Modified Data");
        System.out.println(prototype.getData()); // 输出: Prototype Data
        System.out.println(clonedPrototype.getData()); // 输出: Modified Data
    }
}


⚠️ 注意:示例中的 String 是不可变类型,修改字符串时实际上是创建了新对象,因此不会影响原对象。但如果字段是可变对象(如集合、数组、自定义类),浅拷贝可能会导致引用共享,带来潜在副作用,此时应考虑使用深拷贝。

1.3 建造者模式(Builder Pattern)

核心思想:使用多个简单的对象一步一步构建一个复杂的对象。
实现方式:定义一个建造者接口和具体建造者类,通过建造者类来创建复杂对象。
应用场景:StringBuilder、AlertDialog.Builder。

优点

  • 解耦:将复杂对象的构建与表示解耦。
  • 灵活性:可以根据需要创建不同表示的复杂对象。

Java 示例

// 产品类
public class Product {
    private String partA;
    private String partB;

    // 构造函数
    public Product(String partA, String partB) {
        this.partA = partA;
        this.partB = partB;
    }

    @Override
    public String toString() {
        return "Product [partA=" + partA + ", partB=" + partB + "]";
    }
}

// 建造者接口
public interface Builder {
    void buildPartA();
    void buildPartB();
    Product getResult();
}

// 具体建造者类
public class ConcreteBuilder implements Builder {
    private String partA;
    private String partB;

    @Override
    public void buildPartA() {
        partA = "Part A";
    }

    @Override
    public void buildPartB() {
        partB = "Part B";
    }

    @Override
    public Product getResult() {
        return new Product(partA, partB);
    }
}

// 指导者类
public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.buildPartA();
        builder.buildPartB();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        director.construct();
        Product product = builder.getResult();
        System.out.println(product);
    }
}

1.4 工厂方法模式(Factory Method Pattern)

核心思想:定义一个创建对象的接口,但由子类决定实例化哪个类。
实现方式:将对象的创建逻辑放在子类中,而不是在客户端代码中。
应用场景:日志记录器(文件/数据库日志)、跨平台 UI 组件。

优点

  • 灵活性:可以在运行时决定创建对象的类型。
  • 符合开闭原则:对扩展开放,对修改关闭。

Java 示例

// 产品接口
public interface Product {
    void operation();
}

// 具体产品A
public class ConcreteProductA implements Product {
    @Override
    public void operation() {
        System.out.println("ConcreteProductA operation");
    }
}

// 具体产品B
public class ConcreteProductB implements Product {
    @Override
    public void operation() {
        System.out.println("ConcreteProductB operation");
    }
}

// 工厂接口
public abstract class Creator {
    public abstract Product factoryMethod();
}

// 具体工厂A
public class ConcreteCreatorA extends Creator {
    @Override
    public Product factoryMethod() {
        return new ConcreteProductA();
    }
}

// 具体工厂B
public class ConcreteCreatorB extends Creator {
    @Override
    public Product factoryMethod() {
        return new ConcreteProductB();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Creator creator = new ConcreteCreatorA();
        Product product = creator.factoryMethod();
        product.operation();
    }
}

更多拓展:Java 设计模式之工厂模式

1.5 抽象工厂模式(Abstract Factory Pattern)

核心思想:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
实现方式:通过定义多个工厂接口,每个接口负责创建一组相关的对象。
应用场景:跨平台 UI 组件库(如 Windows/MacOS 风格的按钮和文本框)。
与工厂方法的区别:工厂方法关注单一产品,抽象工厂处理产品族。

优点

  • 一致性:确保创建的一系列对象具有一致性。
  • 扩展性:易于扩展产品系列,而不影响现有代码。

Java 示例

// 产品A接口
public interface ProductA {
    void operationA();
}

// 产品B接口
public interface ProductB {
    void operationB();
}

// 具体产品A1
public class ConcreteProductA1 implements ProductA {
    @Override
    public void operationA() {
        System.out.println("ConcreteProductA1 operationA");
    }
}

// 具体产品B1
public class ConcreteProductB1 implements ProductB {
    @Override
    public void operationB() {
        System.out.println("ConcreteProductB1 operationB");
    }
}

// 具体产品A2
public class ConcreteProductA2 implements ProductA {
    @Override
    public void operationA() {
        System.out.println("ConcreteProductA2 operationA");
    }
}

// 具体产品B2
public class ConcreteProductB2 implements ProductB {
    @Override
    public void operationB() {
        System.out.println("ConcreteProductB2 operationB");
    }
}

// 抽象工厂接口
public interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

// 具体工厂1
public class ConcreteFactory1 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java小白笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值