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

创建型:原型模式

目录

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);}}
}

相关文章:

  • 配置代理服务器访问github、google
  • 408考研逐题详解:2009年第16题
  • 一文掌握工业相机选型计算
  • 【C++】set、map 容器的使用
  • Linux干货(六)
  • 网络安全深度解析:21种常见网站漏洞及防御指南
  • WRFOUT投影转换——兰伯特转等经纬度
  • 单列集合——list集合和五种遍历方式
  • 基于shardingsphere的分库分表方案
  • 【C++】尾置返回类型(Trailing Return Type)总结
  • AI写PPT可以用吗?我测试了3款AI写PPT工具,分享感受
  • Graphics——基于.NET 的 CAD 图形预览技术研究与实现——CAD c#二次开发
  • 【NGINX】 -10 keepalived + nginx + httpd 实现的双机热备+ 负载均衡
  • 湖北理元理律师事务所:债务管理的社会价值探索
  • Science Robotics 封面论文:基于形态学开放式参数化的仿人灵巧手设计用于具身操作
  • 基于Java+MySQL+Servlet的留言系统开发全解析
  • uniapp中的easycom工作机制
  • 构建 TypoView:一个富文本样式预览工具的全流程记录
  • Go 语言中的一等公民(First-Class Citizens)
  • 数位和:从定义到编程实现
  • 上海公办小学验证今起开始,下周一和周二分区进行民办摇号
  • 河南一女子被医院强制带走治疗,官方通报:当值医生停职
  • 官方通报汕头违建豪宅“英之园”将强拆:对有关人员严肃追责问责
  • 2025年“新时代网络文明公益广告”征集展示活动在沪启动
  • 人民日报整版聚焦:外贸产品拓内销提速增量,多地加快推动内外贸一体化
  • 鸿海下调全年营收展望:AI服务器业务强劲,预计今年营收增超50%