设计模式之原型模式
创作时间:
作者:
@小白创作中心
设计模式之原型模式
引用
CSDN
1.
https://blog.csdn.net/Rcain_R/article/details/138031901
1、简单介绍
原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有的实例来创建新对象,而不是通过调用类的构造函数来创建新实例。这种模式适用于需要快速复制大量相同或相似对象,或者创建对象需要消耗大量资源、执行复杂初始化过程,或者需要保护原始对象的状态不受修改等情况。
2、主要角色
- Prototype(原型):定义一个克隆自身的接口,通常包含一个
clone()方法。 - ConcretePrototype(具体原型):实现原型接口,提供克隆自身的具体实现。具体原型类通常包含需要复制的属性和方法。
3、使用场景
- 资源消耗大的对象:当创建对象需要消耗大量资源(如数据库查询、网络通信、复杂计算等)时,使用原型模式可以避免重复创建相同的对象,提高性能。
- 初始化过程复杂的对象:如果对象的初始化过程涉及多个步骤、依赖关系复杂,使用原型模式可以简化对象的创建过程,只需克隆已初始化好的原型即可。
- 保护原始对象状态:在某些场景下,可能需要复制一个对象而不影响原始对象的状态。原型模式可以创建对象的副本,避免直接修改原始对象。
- 动态生成对象:在运行时根据用户需求动态生成新对象,或者需要动态地改变对象的某些属性,可以利用原型模式快速复制并调整对象。
4、Java代码示例
假设我们有一个 Employee 类,包含姓名、职位、薪水等属性,我们使用原型模式来复制员工对象:
import java.util.Date;
public class Employee implements Cloneable {
private String name;
private String position;
private double salary;
private Date hireDate;
public Employee(String name, String position, double salary, Date hireDate) {
this.name = name;
this.position = position;
this.salary = salary;
this.hireDate = (Date) hireDate.clone(); // 防止原始日期对象被修改
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public Date getHireDate() {
return (Date) hireDate.clone(); // 防止原始日期对象被修改
}
public void setHireDate(Date hireDate) {
this.hireDate = (Date) hireDate.clone(); // 防止原始日期对象被修改
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
try {
Employee original = new Employee("John Doe", "Manager", 50000, new Date());
Employee copy = (Employee) original.clone();
copy.setName("Jane Doe");
copy.setSalary(60000);
System.out.println("Original employee: " + original);
System.out.println("Cloned employee: " + copy);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
5、使用过程中可能遇到的问题
- 深拷贝与浅拷贝:默认的
clone()方法实现的是浅拷贝,即只复制对象本身,而不复制其引用的对象。如果对象包含引用类型属性(如数组、集合或其他对象),浅拷贝可能导致原始对象和克隆对象之间的数据共享,修改其中一个对象会影响另一个。对于包含复杂数据结构的对象,需要实现深度拷贝。 - Cloneable接口的局限性:Java的
Cloneable接口是标记接口,没有提供克隆方法。如果忘记实现Cloneable接口或重写clone()方法,调用clone()会抛出CloneNotSupportedException。此外,clone()方法是protected的,需要进行类型转换。 - 对象创建逻辑的分散:如果原型模式与工厂模式、单例模式等混合使用,可能会导致对象创建逻辑分散在多个地方,不易管理。
- 滥用原型模式:不是所有对象都适合使用原型模式。对于简单对象或创建成本较低的对象,直接使用构造函数或工厂方法创建更直观、高效。
6、遇到问题的解决方案
- 深拷贝与浅拷贝解决方案:重写
clone()方法,实现深度拷贝。对于引用类型属性,也需要调用其clone()方法(如果支持)或手动复制其内容。对于不可变对象(如String、Integer等),可以直接引用,无需复制。 - Cloneable接口的局限性解决方案:确保具体原型类实现
Cloneable接口并重写clone()方法。在客户端代码中捕获CloneNotSupportedException,并提供相应的错误处理或提示。为避免类型转换,可以考虑提供一个公共的克隆方法,如createClone()。 - 对象创建逻辑的分散解决方案:明确区分各种模式的职责,尽量保持对象创建逻辑的集中。可以考虑使用工厂方法返回原型对象,或将原型对象的创建与管理交给单例模式的实例。
- 滥用原型模式解决方案:根据对象的复杂度、创建成本等因素,合理选择创建对象的方式。对于简单对象或创建成本较低的对象,优先考虑构造函数或工厂方法。
注意:原型模式通过复制现有对象来创建新对象,适用于资源消耗大、初始化过程复杂、需要保护原始对象状态或动态生成对象的场景。在使用过程中,需要注意深拷贝与浅拷贝的区别、Cloneable 接口的局限性、对象创建逻辑的分散以及模式的适用性等问题,并采取相应的解决方案。
热门推荐
墙面返碱怎么办?从原因分析到解决方案全攻略
Excel中将大量数据按范围分类的多种方法
2025年春晚AI机器人舞蹈背后的科技力量
护栏翻新的经济之道,4000字讲透,怎么翻新合适,如何一步到位!
房子不住怎么申请减免物业费?一文详解物业费减免与违建处理
南京工业大学团队开发仿生眼:自主驱动、高灵敏度、低功耗
医疗介入导管材料大盘点:从PTFE到PEEK的性能与应用
如何看待昨晚的黄金价格走势?这种走势对未来市场有何预示?
损益类科目的借贷方向
哪些二手车值得买?
直击家装行业痛点,贝壳参与编制并发布《家装行业消费者避坑报告》
如何在VSCode中创建和管理工作区
野鸭湖畔,候鸟天堂 —— 延庆冬日观鸟之旅全攻略
北京唯一湿地鸟类保护区:野鸭湖自然风光与生态之美
六成受访者期待为大学生提供从职业规划到实际就业的全方位支持
男生皮肤太黑了怎么样才能让皮肤白
房地产市场周期性对购房者影响几何
如何确定购房的合适时机?市场条件和个人财务状况如何相互影响?
夏季常吃黄瓜好处这么多,常吃的三种养生食谱,快来看看吧!
“三北”工程,一条正在崛起的绿色长城
“三北”工程攻坚战打什么?在哪打?怎么打?国家林草局详解最新进展
唾液分泌过多该怎么办
一文读懂:工业酒精、医用酒精、食用酒精区别与用途
M4A格式详解:为何它成为音频爱好者的首选
【面试技巧】群面技巧及注意事项,教你如何从群面中脱颖而出
守护你的“指尖美学”,指甲油和美甲贴也有大讲究
新手必看!实验室pH计校准快速入门手册
桥梁坍塌预警系统:守护桥梁安全的尖端技术
“数据要素×”典型案例之九 | 多元数据融合 支撑空间与天文科技创新发现
高精度定位在智能驾驶中的关键作用