Java中的23种设计模式
文章目录
- Java中的23种设计模式
-
-
- 一、创建型模式(Creational Patterns)
- 二、结构型模式(Structural Patterns)
- 三、行为型模式(Behavioral Patterns)
-
- 3.1 责任链模式(Chain of Responsibility Pattern)
- 3.2 命令模式(Command Pattern)
- 3.3 迭代器模式(Iterator Pattern)
- 3.4 中介者模式(Mediator Pattern)
- 3.5 备忘录模式(Memento Pattern)
- 3.6 解释器模式(Interpreter Pattern)
- 3.7 状态模式(State Pattern)
- 3.8 策略模式(Strategy Pattern)
- 3.9 模板方法模式(Template Method Pattern)
- 3.10 访问者模式(Visitor Pattern)
- 3.11 观察者模式(Observer Pattern)
- 总结
-
设计模式是软件开发中的最佳实践,帮助开发者在面对复杂设计问题时提供有效的解决方案。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() {