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

java设计模式四,原型模式

什么是原型模式

原型模式是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过实例化新对象的类。这种模式特别适用于创建成本较高的对象,或者需要动态配置对象的场景。

核心概念

原型模式的核心思想是利用已有对象作为"原型",通过复制这个原型来创建新的对象实例。这种方式避免了重复执行耗时的初始化操作,提高了对象创建的效率。

适用场景

原型模式在以下场景中特别有用:

  1. 对象创建成本高:当对象的创建需要从数据库获取数据、进行RPC远程调用或执行复杂计算时
  2. 初始化时间过长:对象初始化过程需要大量时间,通过复制可以避免重复初始化
  3. 需要动态配置:根据运行时状态创建不同配置的对象实例
  4. 需要隔离变化:希望新对象与原始对象相互独立,修改一个不会影响另一个

原型模式的实现方式

基本实现机制

在Java中,原型模式通常通过实现Cloneable接口并重写clone()方法来实现。Cloneable接口是一个标记接口,表示该类的对象可以被克隆。

/*** 基础原型示例* 创建者: YA33*/
class BasicPrototype implements Cloneable {private String id;private Date createTime;public BasicPrototype() {this.createTime = new Date();System.out.println("原型对象创建成功,时间: " + createTime);}public String getId() {return id;}public void setId(String id) {this.id = id;}public Date getCreateTime() {return createTime;}@Overridepublic BasicPrototype clone() throws CloneNotSupportedException {System.out.println("原型对象复制成功");return (BasicPrototype) super.clone();}@Overridepublic String toString() {return "ID: " + id + ", 创建时间: " + createTime;}
}// 测试基础原型
public class BasicPrototypeTest {public static void main(String[] args) throws CloneNotSupportedException {BasicPrototype original = new BasicPrototype();original.setId("ORIG001");BasicPrototype clone = original.clone();clone.setId("CLONE001");System.out.println("原始对象: " + original);System.out.println("克隆对象: " + clone);System.out.println("是否为同一对象: " + (original == clone));}
}

复制方式:浅拷贝与深拷贝

浅拷贝

浅拷贝创建一个新对象,对于基本数据类型,新对象的属性值与原对象完全相同;对于引用数据类型,新对象将复制原对象中引用字段的内存地址,而不是创建新的引用对象。

/*** 浅拷贝示例 - 用户配置文件* 创建者: YA33*/
class UserProfile implements Cloneable {private String username;private Map<String, String> preferences; // 引用类型字段private Date lastLogin; // 引用类型字段public UserProfile(String username) {this.username = username;this.preferences = new HashMap<>();this.lastLogin = new Date();// 初始化默认偏好设置preferences.put("theme", "dark");preferences.put("language", "zh-CN");preferences.put("notifications", "enabled");}@Overridepublic UserProfile clone() throws CloneNotSupportedException {return (UserProfile) super.clone(); // 浅拷贝}public void updatePreference(String key, String value) {preferences.put(key, value);}public void updateLastLogin() {lastLogin = new Date();}public void displayProfile() {System.out.println("用户名: " + username);System.out.println("最后登录: " + lastLogin);System.out.println("偏好设置: " + preferences);}// Getter方法public String getUsername() { return username; }public Map<String, String> getPreferences() { return preferences; }public Date getLastLogin() { return lastLogin; }
}// 测试浅拷贝
public class ShallowCopyTest {public static void main(String[] args) throws CloneNotSupportedException {UserProfile original = new UserProfile("YA33");UserProfile clone = original.clone();System.out.println("=== 修改前 ===");System.out.println("原始配置:");original.displayProfile();System.out.println("\n克隆配置:");clone.displayProfile();// 修改原始对象的引用类型字段original.updatePreference("theme", "light");original.updateLastLogin();System.out.println("\n=== 修改后 ===");System.out.println("原始配置:");original.displayProfile();System.out.println("\n克隆配置:");clone.displayProfile();// 检查是否为同一对象System.out.println("\n偏好设置是否为同一对象: " + (original.getPreferences() == clone.getPreferences()));System.out.println("最后登录时间是否为同一对象: " + (original.getLastLogin() == clone.getLastLogin()));}
}

深拷贝

深拷贝创建一个新对象,并且递归地复制所有引用对象,使得新对象与原始对象完全独立,互不影响。

/*** 深拷贝示例 - 企业部门结构* 创建者: YA33*/
class Department implements Cloneable {private String name;private List<Employee> employees;private Map<String, String> policies;public Department(String name) {this.name = name;this.employees = new ArrayList<>();this.policies = new HashMap<>();}public void addEmployee(Employee employee) {employees.add(employee);}public void addPolicy(String key, String value) {policies.put(key, value);}// 深拷贝实现@Overridepublic Department clone() throws CloneNotSupportedException {Department clone = (Department) super.clone();// 深拷贝员工列表clone.employees = new ArrayList<>();for (Employee employee : this.employees) {clone.employees.add(employee.clone());}// 深拷贝政策映射clone.policies = new HashMap<>(this.policies);return clone;}public void changeDepartmentName(String newName) {this.name = newName;}public void updateEmployeeName(int index, String newName) {if (index >= 0 && index < employees.size()) {employees.get(index).setName(newName);}}public void displayDepartment() {System.out.println("部门名称: " + name);System.out.println("员工列表: ");for (Employee emp : employees) {System.out.println("  - " + emp);}System.out.println("部门政策: " + policies);}
}class Employee implements Cloneable {private String name;private String position;public Employee(String name, String position) {this.name = name;this.position = position;}@Overridepublic Employee clone() throws CloneNotSupportedException {return (Employee) super.clone();}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return name + " (" + position + ")";}// Getter方法public String getName() { return name; }public String getPosition() { return position; }
}// 测试深拷贝
public class DeepCopyTest {public static void main(String[] args) throws CloneNotSupportedException {// 创建原型部门Department original = new Department("技术研发部");original.addEmployee(new Employee("张三", "高级工程师"));original.addEmployee(new Employee("李四", "前端开发"));original.addPolicy("考勤", "弹性工作制");original.addPolicy("休假", "年假15天");// 克隆部门Department clone = original.clone();System.out.println("=== 修改前 ===");System.out.println("原始部门:");original.displayDepartment();System.out.println("\n克隆部门:");clone.displayDepartment();// 修改原始部门original.changeDepartmentName("产品研发部");original.updateEmployeeName(0, "张大师");original.addPolicy("加班", "申请制");System.out.println("\n=== 修改后 ===");System.out.println("原始部门:");original.displayDepartment();System.out.println("\n克隆部门:");clone.displayDepartment();// 检查是否为同一对象System.out.println("\n员工列表是否为同一对象: " + (original.getEmployees() == clone.getEmployees()));System.out.println("政策映射是否为同一对象: " + (original.getPolicies() == clone.getPolicies()));}
}

原型模式的优缺点

优点

  1. 性能优化:避免了重复执行耗时的初始化操作,提高了对象创建效率
  2. 简化对象创建:通过复制现有对象,避免了复杂的构造过程
  3. 动态配置:可以在运行时根据需求动态创建不同配置的对象
  4. 减少子类数量:通过复制不同状态的原型对象,减少了需要创建的子类数量

缺点

  1. 实现复杂:深拷贝实现较为复杂,需要正确处理所有引用对象的复制
  2. 内存消耗:复制大型对象或深层嵌套对象可能消耗较多内存
  3. 依赖克隆能力:需要确保所有需要复制的对象都支持克隆操作
  4. 维护困难:当对象结构发生变化时,需要更新所有相关的克隆方法

实际应用案例

案例一:电商商品复制

/*** 电商商品复制示例* 创建者: YA33*/
class Product implements Cloneable {private String id;private String name;private double price;private List<String> tags;private Map<String, String> specifications;public Product(String id, String name, double price) {this.id = id;this.name = name;this.price = price;this.tags = new ArrayList<>();this.specifications = new HashMap<>();System.out.println("商品创建成功: " + name);}public void addTag(String tag) {tags.add(tag);}public void addSpecification(String key, String value) {specifications.put(key, value);}@Overridepublic Product clone() throws CloneNotSupportedException {Product clone = (Product) super.clone();// 深拷贝标签列表clone.tags = new ArrayList<>(this.tags);// 深拷贝规格映射clone.specifications = new HashMap<>(this.specifications);System.out.println("商品克隆成功: " + name);return clone;}public void applyDiscount(double discountRate) {this.price = this.price * (1 - discountRate);System.out.println("应用折扣: " + (discountRate * 100) + "%, 新价格: " + price);}public void changeName(String newName) {this.name = newName;}public void displayProduct() {System.out.println("商品ID: " + id);System.out.println("商品名称: " + name);System.out.println("商品价格: " + price);System.out.println("商品标签: " + tags);System.out.println("商品规格: " + specifications);}
}public class ProductPrototypeDemo {public static void main(String[] args) throws CloneNotSupportedException {// 创建原型商品Product prototype = new Product("P001", "智能手机", 2999.00);prototype.addTag("新品");prototype.addTag("热销");prototype.addSpecification("屏幕", "6.5英寸");prototype.addSpecification("内存", "8GB");prototype.addSpecification("存储", "128GB");// 克隆商品并应用不同折扣Product discountedProduct = prototype.clone();discountedProduct.applyDiscount(0.1); // 10%折扣Product clearanceProduct = prototype.clone();clearanceProduct.applyDiscount(0.3); // 30%折扣clearanceProduct.addTag("清仓");System.out.println("\n=== 所有商品信息 ===");System.out.println("原型商品:");prototype.displayProduct();System.out.println("\n折扣商品:");discountedProduct.displayProduct();System.out.println("\n清仓商品:");clearanceProduct.displayProduct();}
}

案例二:游戏角色模板

/*** 游戏角色模板示例* 创建者: YA33*/
class GameCharacter implements Cloneable {private String name;private String characterClass;private int level;private Map<String, Integer> attributes;private List<String> skills;public GameCharacter(String name, String characterClass) {this.name = name;this.characterClass = characterClass;this.level = 1;this.attributes = new HashMap<>();this.skills = new ArrayList<>();initializeAttributes();initializeSkills();System.out.println("游戏角色创建成功: " + name);}private void initializeAttributes() {switch (characterClass) {case "战士":attributes.put("力量", 15);attributes.put("敏捷", 10);attributes.put("智力", 5);break;case法师":attributes.put("力量", 5);attributes.put("敏捷", 10);attributes.put("智力", 15);break;case "游侠":attributes.put("力量", 10);attributes.put("敏捷", 15);attributes.put("智力", 5);break;}}private void initializeSkills() {switch (characterClass) {case "战士":skills.add("重击");skills.add("嘲讽");break;case "法师":skills.add("火球术");skills.add("冰冻术");break;case "游侠":skills.add("精准射击");skills.add("陷阱布置");break;}}@Overridepublic GameCharacter clone() throws CloneNotSupportedException {GameCharacter clone = (GameCharacter) super.clone();// 深拷贝属性映射clone.attributes = new HashMap<>(this.attributes);// 深拷贝技能列表clone.skills = new ArrayList<>(this.skills);System.out.println("游戏角色克隆成功: " + name);return clone;}public void levelUp() {level++;System.out.println(name + " 升级了! 当前等级: " + level);// 根据职业增加属性switch (characterClass) {case "战士":attributes.put("力量", attributes.get("力量") + 2);attributes.put("敏捷", attributes.get("敏捷") + 1);attributes.put("智力", attributes.get("智力") + 0);break;case "法师":attributes.put("力量", attributes.get("力量") + 0);attributes.put("敏捷", attributes.get("敏捷") + 1);attributes.put("智力", attributes.get("智力") + 2);break;case "游侠":attributes.put("力量", attributes.get("力量") + 1);attributes.put("敏捷", attributes.get("敏捷") + 2);attributes.put("智力", attributes.get("智力") + 0);break;}}public void learnSkill(String newSkill) {skills.add(newSkill);System.out.println(name + " 学会了新技能: " + newSkill);}public void changeName(String newName) {this.name = newName;}public void displayCharacter() {System.out.println("角色名: " + name);System.out.println("职业: " + characterClass);System.out.println("等级: " + level);System.out.println("属性: " + attributes);System.out.println("技能: " + skills);}
}public class GameCharacterPrototypeDemo {public static void main(String[] args) throws CloneNotSupportedException {// 创建原型角色GameCharacter warriorTemplate = new GameCharacter("战士模板", "战士");GameCharacter mageTemplate = new GameCharacter("法师模板", "法师");GameCharacter rangerTemplate = new GameCharacter("游侠模板", "游侠");// 克隆角色并个性化GameCharacter player1 = warriorTemplate.clone();player1.changeName("狂暴战士");player1.levelUp();player1.learnSkill("旋风斩");GameCharacter player2 = mageTemplate.clone();player2.changeName("冰霜法师");player2.levelUp();player2.levelUp();player2.learnSkill("暴风雪");System.out.println("\n=== 玩家角色信息 ===");System.out.println("玩家1:");player1.displayCharacter();System.out.println("\n玩家2:");player2.displayCharacter();System.out.println("\n=== 模板角色信息 ===");System.out.println("战士模板:");warriorTemplate.displayCharacter();}
}

案例三:文档模板系统

/*** 文档模板系统示例* 创建者: YA33*/
class DocumentTemplate implements Cloneable {private String title;private String content;private Map<String, String> variables;private List<String> sections;private Date createdDate;public DocumentTemplate(String title) {this.title = title;this.content = "";this.variables = new HashMap<>();this.sections = new ArrayList<>();this.createdDate = new Date();System.out.println("文档模板创建成功: " + title);}public void addSection(String section) {sections.add(section);content += section + "\n";}public void setVariable(String key, String value) {variables.put(key, value);}public void replaceVariables() {for (Map.Entry<String, String> entry : variables.entrySet()) {content = content.replace("{{" + entry.getKey() + "}}", entry.getValue());}}@Overridepublic DocumentTemplate clone() throws CloneNotSupportedException {DocumentTemplate clone = (DocumentTemplate) super.clone();// 深拷贝变量映射clone.variables = new HashMap<>(this.variables);// 深拷贝章节列表clone.sections = new ArrayList<>(this.sections);// 重置内容并重新应用变量clone.content = this.content;clone.replaceVariables();System.out.println("文档模板克隆成功: " + title);return clone;}public void customizeTemplate(String newTitle, Map<String, String> newVariables) {this.title = newTitle;this.variables.putAll(newVariables);replaceVariables();}public void displayDocument() {System.out.println("=== " + title + " ===");System.out.println("创建日期: " + createdDate);System.out.println("内容:");System.out.println(content);System.out.println("变量: " + variables);}
}public class DocumentTemplateDemo {public static void main(String[] args) throws CloneNotSupportedException {// 创建协议模板DocumentTemplate agreementTemplate = new DocumentTemplate("通用协议模板");agreementTemplate.addSection("协议标题: {{agreement_title}}");agreementTemplate.addSection("协议双方: {{party_a}} 与 {{party_b}}");agreementTemplate.addSection("协议内容: {{agreement_content}}");agreementTemplate.addSection("签署日期: {{sign_date}}");// 设置模板变量agreementTemplate.setVariable("agreement_title", "合作协议");agreementTemplate.setVariable("party_a", "公司A");agreementTemplate.setVariable("party_b", "公司B");agreementTemplate.setVariable("agreement_content", "双方同意在以下领域合作...");agreementTemplate.setVariable("sign_date", "2023年12月15日");// 克隆并定制不同协议DocumentTemplate nda = agreementTemplate.clone();Map<String, String> ndaVariables = new HashMap<>();ndaVariables.put("agreement_title", "保密协议");ndaVariables.put("agreement_content", "双方同意对以下信息保密...");nda.customizeTemplate("保密协议", ndaVariables);DocumentTemplate serviceAgreement = agreementTemplate.clone();Map<String, String> serviceVariables = new HashMap<>();serviceVariables.put("agreement_title", "服务协议");serviceVariables.put("agreement_content", "甲方同意向乙方提供以下服务...");serviceAgreement.customizeTemplate("服务协议", serviceVariables);System.out.println("\n=== 所有文档 ===");System.out.println("原始模板:");agreementTemplate.displayDocument();System.out.println("\n保密协议:");nda.displayDocument();System.out.println("\n服务协议:");serviceAgreement.displayDocument();}
}

原型模式的最佳实践

  1. 合理选择拷贝方式:根据业务需求选择浅拷贝或深拷贝
  2. 注意循环引用:在深拷贝时,需要注意对象之间可能存在的循环引用问题
  3. 考虑性能影响:对于大型对象或复杂结构,深拷贝可能带来性能问题
  4. 保持接口一致性:确保克隆后的对象与原始对象在行为上保持一致
  5. 处理异常情况:妥善处理克隆过程中可能出现的异常

总结

原型模式是一种强大的创建型设计模式,它通过复制现有对象来创建新对象,避免了重复的初始化操作,提高了系统性能。在实际开发中,我们需要根据具体需求选择合适的拷贝方式(浅拷贝或深拷贝),并注意处理好对象之间的引用关系。

通过合理使用原型模式,我们可以创建出更加灵活、高效的系统,特别是在需要创建大量相似对象或对象创建成本较高的场景中,原型模式能够发挥重要作用。

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

相关文章:

  • 【NOIP 2024 T2】遗失的赋值
  • TypeScript学习笔记1
  • Android普通应用切到后台后,多长时间会被系统回收
  • 【Elasticsearch面试精讲 Day 21】地理位置搜索与空间查询
  • 【Android】View 的滑动
  • 【深度学习的优化理论】如何理解OT与欧几里得距离均值的区别
  • 【Android】Room数据库的基本使用
  • 项目:仿muduo库的高并发服务器
  • Oracle普通用户报错ORA-31603处理
  • 网络安全期末大论文
  • 23种设计模式之【工厂方法模式】-核心原理与 Java实践
  • cocos 添加背景,帧动画,贴图
  • 亚马逊云科技重磅推出 Amazon S3 Vectors:首款大规模支持原生向量的云存储服务
  • SQLite Expert:一款功能强大的SQLite管理工具
  • Python 2025:供应链安全威胁与防御实战
  • 队列+宽搜(BFS)-429.N叉树的层序遍历-力扣(LeetCode)
  • 【Linux命令从入门到精通系列指南】rm 命令详解:安全删除文件与目录的终极实战手册
  • Springboot使用dockerfile-maven-plugin部署镜像
  • 安卓蓝牙键盘和鼠标6.10.4去更新汉化版 手机变为蓝牙键盘和鼠标
  • 工作笔记-----lwip的内存管理策略解析
  • 量子计算学习笔记(1)
  • Python爬虫基础与应用
  • Rabbitmq 集群初始化,配置导入
  • 云计算与虚拟化技术详解
  • elasticsearch 的配制
  • React学习教程,从入门到精通,React Hook 详解 —— 语法知识点、使用方法与案例代码(26)
  • ELK日志分析性能瓶颈问题排查与解决实践指南
  • 【Unity】【Photon】Fusion2中的匹配API 学习笔记
  • (3-1) Html
  • 《人机协同的边界与价值:开放世界游戏系统重构中的AI工具实战指南》