首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >23种设计模式之原型模式

23种设计模式之原型模式

作者头像
紫风
发布2025-10-14 18:35:27
发布2025-10-14 18:35:27
6500
代码可运行
举报
运行总次数:0
代码可运行

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

一、原型模式概述
  • 英文名称:Prototype
  • 核心目标通过复制现有对象来创建新对象,避免重复初始化带来的性能开销。
  • 设计思想:利用 clone() 方法实现对象的快速复制,支持动态扩展对象类型。

二、优缺点
优点
  1. 性能优化:跳过复杂构造过程,直接复制内存中的对象。
  2. 动态性高:运行时动态新增或修改对象类型(如通过注册表管理原型)。
  3. 避免构造约束:绕过构造函数限制,创建不可变对象副本。
缺点
  1. 深拷贝复杂度:需处理对象内部引用类型的深拷贝问题。
  2. 侵入性设计:需实现 Cloneable 接口,可能违反某些设计原则(如接口隔离)。
  3. 破坏封装性clone() 方法可能访问私有字段,需谨慎实现。

三、应用场景
  1. 对象初始化成本高:如数据库查询结果、复杂计算后的配置对象。
  2. 需要快速创建大量相似对象:如游戏中的敌人复制、粒子系统。
  3. 保护性拷贝:防止外部修改共享对象(如线程安全的数据传递)。
  4. 动态配置系统:运行时切换对象类型(如 UI 主题原型切换)。

四、代码实现与注释

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


1. 实现 Cloneable 接口(浅拷贝)
代码语言:javascript
代码运行次数:0
运行
复制
import java.util.List;

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

    public DocumentTemplate(String title, List<String> 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);
    }
}
客户端调用(浅拷贝问题示例)
代码语言:javascript
代码运行次数:0
运行
复制
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 原始文档
        List<String> 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);
    }
}
输出结果(浅拷贝问题)
代码语言:javascript
代码运行次数:0
运行
复制
--- 原文档 ---
Title: 原始文档
Content: 第一段
第二段
新增段落   // 原对象的 paragraphs 被修改!
--- 副本 ---
Title: 副本文档
Content: 第一段
第二段
新增段落

2. 深拷贝实现(解决浅拷贝问题)
代码语言:javascript
代码运行次数:0
运行
复制
/**
 * 深拷贝原型类:通过手动复制引用对象
 */
public class DeepDocumentTemplate implements Cloneable {
    private String title;
    private List<String> paragraphs;

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

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

    // 省略其他方法...
}
客户端调用(深拷贝修复问题)
代码语言:javascript
代码运行次数:0
运行
复制
public class Client {
    public static void main(String[] args) {
        List<String> 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);
    }
}
输出结果(深拷贝隔离)
代码语言:javascript
代码运行次数:0
运行
复制
--- 原文档 ---
Title: 原始文档
Content: 第一段
第二段
--- 副本 ---
Title: 副本文档
Content: 第一段
第二段
新增段落

五、模式结构图
代码语言:javascript
代码运行次数:0
运行
复制
+----------------+          +----------------+
|   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() 方法,是原型模式的典型应用。合理使用该模式可显著提升系统性能与灵活性。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、原型模式概述
  • 二、优缺点
    • 优点:
    • 缺点:
  • 三、应用场景
  • 四、代码实现与注释
    • 1. 实现 Cloneable 接口(浅拷贝)
    • 客户端调用(浅拷贝问题示例)
    • 输出结果(浅拷贝问题)
    • 2. 深拷贝实现(解决浅拷贝问题)
    • 客户端调用(深拷贝修复问题)
    • 输出结果(深拷贝隔离)
  • 五、模式结构图
  • 六、与其他模式的关系
  • 七、最佳实践
  • 八、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档