当前位置: 首页 > article >正文

创建型:原型模式

目录

1、核心思想

2、实现方式

2.1 基本结构

2.2 代码示例(Java)

3、适用场景

4、new与clone实际场景建议


1、核心思想

目的:通过复制(克隆)现有对象来创建新对象,而不是通过new关键字实例化。对于那些有非常复杂的初始化过程的对象或者是需要耗费大量资源的情况,原型模式是更好的选择。

核心价值:通过克隆避免重复初始化,提升性能。

克隆的优势:克隆操作时Java虚拟机会进行内存操作,直接拷贝原型对象数据流生成新的副本对象,绝不会拖泥带水地触发一些多余的复杂操作(如类加载、实例化、初始化等)​,所以其效率远远高于“new”关键字所触发的实例化操作。

注意

1> 浅拷贝与深拷贝

浅拷贝:复制原始类型的值,引用类型只拷贝地址引用(指针),与原对象的应用变量地址指向的内存对象是同一个。

深拷贝:需要在clone方法里,自行递归实现引用对象的clone和赋值,确保与原对象完全独立,注意这里的引用对象也需要实现Cloneable接口。递归赋值会大幅增加资源消耗。

2> 依赖 Cloneable 接口:若类未实现 Cloneable,调用 clone() 会抛出 CloneNotSupportedException。

性能对比

场景new 的消耗clone() 的消耗
简单对象(浅拷贝)较高(跳过构造函数)
复杂对象(深拷贝)可能更高(递归复制)

优缺点

优点缺点
避免重复初始化,提升性能深拷贝实现复杂(尤其循环引用时)
动态生成对象配置(修改原型即可)需为每个类实现克隆方法
隐藏对象创建细节,降低耦合度可能违背构造函数约束(如私有状态)

2、实现方式

2.1 基本结构

  • 抽象原型接口(Prototype):声明克隆方法(如 clone()),对应Cloneable接口。

  • 具体原型实现类(ConcretePrototype):实现克隆方法,定义如何复制自身,实现方法中调用super.clone()即可得到新的浅克隆的对象。

  • 客户端(Client):通过原型对象的 clone() 方法生成新对象。

2.2 代码示例(Java)

// 1. 抽象原型接口  Cloneable// 2. 具体原型类
public class ConcretePrototype implements Cloneable {private String field;private List<String> listField; // 引用类型字段private ObjectTmp objectTmp; // 引用类型字段,ObjectTmp类需要实现Cloneablepublic ConcretePrototype(String field, List<String> listField) {this.field = field;this.listField = listField;}publice void setListField(List<String> listField) {this.listField = listField;}publice void setObjectTmp(ObjectTmp objectTmp) {this.objectTmp= objectTmp;}@Overridepublic ConcretePrototype clone() {try {// 浅拷贝(直接复制引用)ConcretePrototype copy = (ConcretePrototype) super.clone();// 深拷贝(需手动复制引用类型字段)copy.setListField(new ArrayList<>(this.listField));copy.setObjectTmp(this.objectTmp.clone());return copy;} catch (CloneNotSupportedException e) {throw new AssertionError();}}
}// 3. 客户端使用
public class Client {public static void main(String[] args) {ConcretePrototype prototype = new ConcretePrototype("value", Arrays.asList("a", "b"));ConcretePrototype clone = (ConcretePrototype) prototype.clone();}
}

3、适用场景

  • 对象创建成本高:如需要复杂计算的配置对象。

  • 动态生成对象变体:例如游戏中生成不同属性的敌人。

  • 需要隔离对象状态:保证原对象与新对象互不影响。

  • 结合工厂模式使用:用原型注册表管理多种原型对象。

4、new与clone实际场景建议

  • 优先用 new

    • 代码更清晰,符合常规对象创建逻辑。

    • 避免深浅拷贝的潜在问题(如意外共享引用)。

  • 谨慎用 clone()

    • 仅在需要高效复制简单对象时使用(如缓存对象、原型模式)。

    • 确保正确实现 Cloneable 接口并处理深浅拷贝。

  • 替代方案

    • 工厂方法/构建器模式:灵活控制对象创建流程。

    • 序列化/反序列化:实现深拷贝,但性能较差。

public class DeepCopyUtil {public static <T extends Serializable> T deepCopy(T object) {try (ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos)) {oos.writeObject(object);try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis)) {return (T) ois.readObject();}} catch (IOException | ClassNotFoundException e) {throw new RuntimeException("Deep copy failed", e);}}
}

http://www.lryc.cn/news/2379084.html

相关文章:

  • 浅谈“量子计算应用:从基础原理到行业破局”
  • Java面试攻略:从Spring Boot到微服务架构的深入探讨
  • 关于文件分片的介绍和应用
  • Tapered Off-Policy REINFORCE_ 如何为LLM实现稳定高效的策略优化?
  • 使用lvm进行磁盘分区
  • [Java实战]Spring Boot整合Elasticsearch(二十六)
  • 图像分割(1)U-net
  • 数位和:从定义到编程实现
  • 2025抓包工具Reqable手机抓包HTTPS亲测简单好用-快速跑通
  • 使用 Auto-Keras 进行自动化机器学习
  • python 自动化教程
  • 简单使用Slidev和PPTist
  • RISC-V 开发板 MUSE Pi Pro V2D图像加速器测试,踩坑介绍
  • 人工智能100问☞第26问:什么是贝叶斯网络?
  • c++多线程debug
  • 如何畅通需求收集渠道,获取用户反馈?
  • 标准库、HAl库和LL库(PC13初始化)
  • LangGraph深度解析:构建持久化、可观测的智能体工作流
  • 设备预测性维护的停机时间革命:中讯烛龙如何用AI重构工业设备管理范式
  • day29 python深入探索类装饰器
  • Python数据分析三剑客:NumPy、Pandas与Matplotlib安装指南与实战入门
  • 二:操作系统之进程控制块(PCB)
  • Spring-Beans的生命周期的介绍
  • Android 自定义悬浮拖动吸附按钮
  • 通过串口设备的VID PID动态获取串口号(C# C++)
  • [创业之路-361]:企业战略管理案例分析-2-战略制定-使命、愿景、价值观的失败案例
  • Window远程连接Linux桌面版
  • 一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting
  • ARM A64 STR指令
  • C#中的成员常量:编译时的静态魔法