23种设计模式之原型模式

以下是 原型模式 (Prototype Pattern) 的详细介绍,包含定义、优缺点、应用场景及代码实现:


一、原型模式概述

  • 英文名称:Prototype

  • 核心目标通过复制现有对象来创建新对象,避免重复初始化带来的性能开销。

  • 设计思想:利用 clone() 方法实现对象的快速复制,支持动态扩展对象类型。


二、优缺点

优点
  1. 性能优化:跳过复杂构造过程,直接复制内存中的对象。

  2. 动态性高:运行时动态新增或修改对象类型(如通过注册表管理原型)。

  3. 避免构造约束:绕过构造函数限制,创建不可变对象副本。

缺点
  1. 深拷贝复杂度:需处理对象内部引用类型的深拷贝问题。

  2. 侵入性设计:需实现 Cloneable 接口,可能违反某些设计原则(如接口隔离)。

  3. 破坏封装性clone() 方法可能访问私有字段,需谨慎实现。


三、应用场景

  1. 对象初始化成本高:如数据库查询结果、复杂计算后的配置对象。

  2. 需要快速创建大量相似对象:如游戏中的敌人复制、粒子系统。

  3. 保护性拷贝:防止外部修改共享对象(如线程安全的数据传递)。

  4. 动态配置系统:运行时切换对象类型(如 UI 主题原型切换)。


四、代码实现与注释

以下通过 文档模板复制 的案例演示原型模式,包含浅拷贝与深拷贝实现:


1. 实现 Cloneable 接口(浅拷贝)

import java.util.List;

/**
 * 原型类:文档模板(实现 Cloneable 接口)
 */
public class DocumentTemplate implements Cloneable {
    private String title;
    private List paragraphs;  // 引用类型(浅拷贝共享该引用)

    public DocumentTemplate(String title, List paragraphs) {
        this.title = title;
        this.paragraphs = paragraphs;
    }

    /**
     * 浅拷贝实现:直接调用 Object.clone() 
     */
    @Override
    public DocumentTemplate clone() throws CloneNotSupportedException {
        return (DocumentTemplate) super.clone();
    }

    // 修改标题(演示浅拷贝影响)
    public void setTitle(String title) {
        this.title = title;
    }

    // 添加段落(演示浅拷贝问题)
    public void addParagraph(String text) {
        paragraphs.add(text);
    }

    @Override
    public String toString() {
        return "Title: " + title + "\nContent: " + String.join("\n", paragraphs);
    }
}
客户端调用(浅拷贝问题示例)

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 原始文档
        List paragraphs = new ArrayList<>(List.of("第一段", "第二段"));
        DocumentTemplate original = new DocumentTemplate("原始文档", paragraphs);
        
        // 浅拷贝副本
        DocumentTemplate copy = original.clone();
        copy.setTitle("副本文档");  // 修改基本类型字段(不影响原对象)
        copy.addParagraph("新增段落");  // 修改引用类型字段(影响原对象!)

        System.out.println("--- 原文档 ---\n" + original);
        System.out.println("--- 副本 ---\n" + copy);
    }
}
输出结果(浅拷贝问题)

--- 原文档 ---
Title: 原始文档
Content: 第一段
第二段
新增段落   // 原对象的 paragraphs 被修改!
--- 副本 ---
Title: 副本文档
Content: 第一段
第二段
新增段落

2. 深拷贝实现(解决浅拷贝问题)

/**
 * 深拷贝原型类:通过手动复制引用对象
 */
public class DeepDocumentTemplate implements Cloneable {
    private String title;
    private List paragraphs;

    public DeepDocumentTemplate(String title, List paragraphs) {
        this.title = title;
        this.paragraphs = new ArrayList<>(paragraphs);  // 防御性拷贝
    }

    /**
     * 深拷贝实现:手动创建新对象
     */
    @Override
    public DeepDocumentTemplate clone() {
        // 1. 基本类型字段直接复制
        String clonedTitle = this.title;
        
        // 2. 引用类型字段创建新实例
        List clonedParagraphs = new ArrayList<>(this.paragraphs);
        
        return new DeepDocumentTemplate(clonedTitle, clonedParagraphs);
    }

    // 省略其他方法...
}
客户端调用(深拷贝修复问题)

public class Client {
    public static void main(String[] args) {
        List paragraphs = new ArrayList<>(List.of("第一段", "第二段"));
        DeepDocumentTemplate original = new DeepDocumentTemplate("原始文档", paragraphs);
        
        DeepDocumentTemplate copy = original.clone();
        copy.setTitle("副本文档");
        copy.addParagraph("新增段落");

        System.out.println("--- 原文档 ---\n" + original);
        System.out.println("--- 副本 ---\n" + copy);
    }
}
输出结果(深拷贝隔离)

--- 原文档 ---
Title: 原始文档
Content: 第一段
第二段
--- 副本 ---
Title: 副本文档
Content: 第一段
第二段
新增段落

五、模式结构图

+----------------+          +----------------+
|   Prototype    |          |   Client       |
+----------------+          +----------------+
| clone():Prototype         |                |
+----------------+          +----------------+
         ^                           |
         |                           |
+----------------+          +----------------+
| ConcretePrototype        |                |
+----------------+          +----------------+
| clone():Prototype        |                |
+----------------+          +----------------+

六、与其他模式的关系

  1. 工厂模式:原型模式可替代工厂方法,通过克隆生成对象。

  2. 组合模式:原型模式常用于复制组合结构的对象(如树形菜单)。

  3. 备忘录模式:原型可用于实现备忘录的快照存储与恢复。


七、最佳实践

  1. 深拷贝工具:使用序列化(如 ObjectOutputStream)或工具库(Apache Commons Lang 的 SerializationUtils)简化深拷贝。

  2. 原型注册表:维护一个全局原型池,支持动态获取和扩展原型。

  3. 避免 final 字段clone() 方法无法修改 final 字段,需谨慎设计。


八、总结

  • 核心价值:通过复制优化对象创建性能,支持动态对象扩展。

  • 适用场景:对象初始化成本高、需快速生成相似副本、避免构造约束的系统。

  • 关键实现:实现 Cloneable 接口 + 重写 clone() 方法 + 处理深拷贝。

Java 中 ArrayListHashMap 等集合类均实现了 clone() 方法,是原型模式的典型应用。合理使用该模式可显著提升系统性能与灵活性。

你可能感兴趣的:(设计模式,设计模式,原型模式,架构,后端)