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

23种设计模式之【原型模式】-核心原理与 Java实践

文章目录

  • 原型模式(Prototype Pattern)
  • 核心原理
  • Java 实践示例
  • 克隆方式详解
  • 原型模式的应用场景

原型模式(Prototype Pattern)

原型模式是 23 种设计模式中的一种创建型模式,其核心思想是通过复制(克隆)现有对象来创建新对象,而不是通过 new 关键字新建。这种模式适用于创建成本较高(如初始化步骤复杂、耗时)或需要频繁创建相似对象的场景,通过复制原型对象可以提高创建效率。

核心原理

原型接口(Prototype)
声明克隆方法(通常为clone()),定义复制自身的接口
在 Java 中通常通过实现Cloneable接口来标识可克隆的类
具体原型(Concrete Prototype)
实现原型接口的克隆方法,完成自身的复制
包含需要被复制的属性和方法
客户端(Client)
通过调用原型对象的克隆方法来创建新对象
无需知道具体的创建细节,只需操作原型接口

原型模式的核心是 “对象克隆”,通过复制已有对象来生成新对象,避免了重复的初始化过程,提高了对象创建效率。

Java 实践示例

以 “文档模板克隆” 为例实现原型模式:
文档包含标题、内容和格式设置,创建过程复杂
通过克隆现有文档模板快速生成新文档

package com.example.demo;public class PrototypePattern {public static void main(String[] args) throws CloneNotSupportedException {// 创建原型文档(模板)Document prototype = new Document();prototype.setTitle("周报模板");prototype.setContent("本周工作内容:\n1. \n2. \n3.");prototype.setFormat(new Format("Arial", 12, "black"));System.out.println("=== 原型文档 ===");prototype.show();// 克隆原型创建新文档1Document doc1 = prototype.clone();doc1.setTitle("张三的周报");doc1.setContent("本周工作内容:\n1. 完成需求分析\n2. 设计数据库\n3. 编写接口文档");// 克隆原型创建新文档2Document doc2 = prototype.clone();doc2.setTitle("李四的周报");doc2.setContent("本周工作内容:\n1. 开发用户模块\n2. 修复3个BUG\n3. 编写单元测试");System.out.println("\n=== 克隆的文档1 ===");doc1.show();System.out.println("\n=== 克隆的文档2 ===");doc2.show();// 验证克隆对象与原型的关系System.out.println("\n原型与克隆对象是否为同一实例:" + (prototype == doc1));System.out.println("克隆对象的格式是否与原型相同:" + (prototype.getFormat() == doc1.getFormat()));//=== 原型文档 ===//标题:周报模板//内容:本周工作内容://1.//2.//3.//格式:字体=Arial, 字号=12, 颜色=black////=== 克隆的文档1 ===//标题:张三的周报//内容:本周工作内容://1. 完成需求分析//2. 设计数据库//3. 编写接口文档//格式:字体=Arial, 字号=12, 颜色=black////=== 克隆的文档2 ===//标题:李四的周报//内容:本周工作内容://1. 开发用户模块//2. 修复3个BUG//3. 编写单元测试//格式:字体=Arial, 字号=12, 颜色=black////原型与克隆对象是否为同一实例:false//克隆对象的格式是否与原型相同:true}// 文档格式类public static class Format {private String font;    // 字体private int fontSize;   // 字号private String color;   // 颜色public Format(String font, int fontSize, String color) {this.font = font;this.fontSize = fontSize;this.color = color;}@Overridepublic String toString() {return "格式:字体=" + font + ", 字号=" + fontSize + ", 颜色=" + color;}}// 文档类(实现原型接口)public static class Document implements Cloneable {private String title;   // 标题private String content; // 内容private Format format;  // 格式// 克隆方法@Overridepublic Document clone() throws CloneNotSupportedException {// 调用Object类的clone()方法实现浅克隆return (Document) super.clone();}// 显示文档信息public void show() {System.out.println("标题:" + title);System.out.println("内容:" + content);System.out.println(format);}// getter和setter方法public String getTitle() { return title; }public void setTitle(String title) { this.title = title; }public String getContent() { return content; }public void setContent(String content) { this.content = content; }public Format getFormat() { return format; }public void setFormat(Format format) { this.format = format; }}
}

克隆方式详解

  • 浅克隆(Shallow Clone):
    特点:只复制对象本身和基本数据类型字段,引用类型字段只复制引用,不复制引用指向的对象
    Java 实现:通过Object.clone()方法实现,默认是浅克隆
    适用场景:对象中不含引用类型,或引用类型是不可变对象(如 String)
  • 深克隆(Deep Clone):
    特点:不仅复制对象本身,还递归复制所有引用类型字段指向的对象
    Java 实现:
    方式一:重写clone()方法,手动克隆所有引用类型字段
    方式二:通过序列化(Serializable)实现

深克隆实现示例(方式一):

@Override
public Document clone() throws CloneNotSupportedException {// 先浅克隆得到基本类型字段Document clone = (Document) super.clone();// 手动克隆引用类型字段clone.format = new Format(this.format.font, this.format.fontSize, this.format.color);return clone;
}

原型模式的应用场景

  • 对象创建成本高:
    初始化步骤复杂(如需要读取配置文件、数据库连接)
    例如:报表对象、复杂的业务对象
  • 需要频繁创建相似对象:
    对象大部分属性相同,只有少数属性不同
    例如:文档模板、邮件模板、订单模板
  • 避免构造函数的限制:
    当无法通过构造函数创建对象(如私有构造函数)
    例如:克隆单例对象的特殊场景
  • 框架中的应用:
    Java 中的Object.clone()方法是原型模式的基础
    Spring 中的BeanUtils.copyProperties()实现对象复制
    原型模式与工厂模式结合,通过克隆生成产品

原型模式的优势在于简化对象创建过程,提高创建效率,尤其适合创建复杂对象或大量相似对象的场景。使用时需根据需求选择浅克隆或深克隆,避免引用共享导致的意外问题。

http://www.dtcms.com/a/393610.html

相关文章:

  • Netty 重放解码器ReplayingDecoder揭秘:重写轻量异常机制 和 ConstantPool
  • getgeo 生物信息 R语言 表型信息表”“样本信息表”或“临床信息表 phenodata phenotype data
  • OceanBase备租户创建(二):通过BACKUP DATABASE PLUS ARCHIVELOG
  • Linux文件打包压缩与软件安装管理完全指南
  • KingbaseES数据备份操作详解(图文教程)
  • 中断屏蔽实现方法-ARM内核
  • Kotlin 协程之 SharedFlow 与 StateFlow 深度解析
  • python爬虫(请求+解析+案例)
  • 111-Christopher-Dall_Arm-Timers-and-Fire:Arm架构计时器与半虚拟化时间
  • switch缺少break出现bug
  • 【自然语言处理】(3) --RNN循环神经网络
  • C# 中的 ReferenceEquals 方法
  • BERT:用于语言理解的深度双向Transformer预训练【简单分析】
  • 力扣hot100:两数相加(模拟竖式加法详解)(2)
  • Zotero + Word 插件管理参考文献的引用
  • 用Python一键整理文件:自动分类DOCX与PDF,告别文件夹杂乱
  • Ubuntu部署Elasticsearch教程
  • 61.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--提取金额
  • 一款基于 .NET 开源、免费、命令行式的哔哩哔哩视频内容下载工具
  • Win Semi宣布推出线性优化的GaN工艺
  • 考研408计算机网络2025年第38题真题解析
  • C++编写的经典贪吃蛇游戏
  • 风险预测模型原理
  • PS练习5:利用翻转制作图像倒影
  • 平替Jenkins,推荐一款国产开源免费的CICD工具 - Arbess
  • aws 实战小bug
  • NumPy 系列(一):numpy 数组基础
  • VSCode 的 launch.json 配置
  • OpenLayers地图交互 -- 章节六:范围交互详解
  • 分布式专题——15 ZooKeeper特性与节点数据类型详解