
java 原型模式(大话设计模式)
发布日期:2021-05-19 21:35:53
浏览次数:10
分类:精选文章
本文共 5281 字,大约阅读时间需要 17 分钟。
原型模式(PrototypePattern)是一种经典的软件设计模式,其核心思想是利用原型实例来指定创建对象的类型,并通过复制这些原型来生成新的对象。这种模式非常适合对象的创造和复制场景,尤其在需要共享单元格或减少对象构造开销的时候表现优异。
浅拷贝(Shallow Copy)
浅拷贝是实现原型模式的基本方式。在浅拷贝中,新对象的每个成员字段都是直接引用原型对象的字段。也就是说,只有指针进行了复制,而不是拷贝数据。此时,原型对象的状态会直接影响新对象的状态,导致共享的单元格问题。下面是一个浅拷贝的例子:
public class WorkExperience { private String workDate; private String company; // ... getter 和 setter 方法}
public class Resume implements Cloneable { private String name; private String sex; private int age; private WorkExperience workExperience; public Resume(String name) { this.name = name; workExperience = new WorkExperience(); } // ... setter 方法定义 @Override public Object clone() throws CloneNotSupportedException { return super.clone(); }}
客户端示例:
public class Client { public static void main(String[] args) throws CloneNotSupportedException { Resume r0 = new Resume("大鸟"); r0.setPersonalInfo("男", "29"); r0.setWorkExperience("1998-2000", "xx公司"); Resume r1 = (Resume) r0.clone(); r1.setWorkExperience("1998-2006", "yy企业"); Resume r2 = (Resume) r0.clone(); r2.setWorkExperience("1998-2003", "zz公司"); // 浅拷贝后的结果会共享同一工作经历对象 System.out.println("<-- 浅拷贝 -->"); r0.display(); r1.display(); r2.display(); }}
深拷贝(Deep Copy)
深拷贝是在浅拷贝的基础上,对每个引用字段进行深拷贝,确保新对象对其成员字段的引用是独立的。这个过程通常涉及序列化或反序列化,以确保所有相关对象都被正确拷贝。下面是一个深拷贝的实现示例:
public class WorkExperience { private String workDate; private String company; // ...getter 和 setter 方法 @Override public Object clone() throws CloneNotSupportedException { return super.clone(); }}
public class Resume implements Cloneable { private String name; private String sex; private int age; private WorkExperience workExperience; public Resume(String name) { this.name = name; this.workExperience = new WorkExperience(); } public Resume(WorkExperience workExperience) throws CloneNotSupportedException { this.workExperience = (WorkExperience) workExperience.clone(); } // ... setter 方法定义 @Override public Object clone() throws CloneNotSupportedException { Resume resume = new Resume((WorkExperience) this.workExperience.clone()); resume.name = this.name; resume.sex = this.sex; resume.age = this.age; return resume; }}
客户端示例:
public class Client { public static void main(String[] args) throws CloneNotSupportedException, IOException { Resume r0 = new Resume("大鸟"); r0.setPersonalInfo("男", "29"); r0.setWorkExperience("1998-2000", "xx公司"); Resume r1 = (Resume) r0.clone(); r1.setWorkExperience("1998-2006", "yy公司"); Resume r2 = (Resume) r0.clone(); r2.setWorkExperience("1998-2003", "zz公司"); // 深拷贝后的每个对象都有独立的业务对象 System.out.println("<-- 深拷贝 -->"); r0.display(); r1.display(); r2.display(); }}
通过对象序列化实现深度拷贝
在某些情况下,特别是对象图结构较为复杂时,我们可以采用对象序列化的方式来实现深度拷贝。这种方法的优势在于其简单且适用于所有支持序列化的对象。以下是一个使用序列化实现深度拷贝的例子:
public class Resume implements Serializable { private static final long serialVersionUID = -4410449301166191440L; private String name; private String sex; private int age; private WorkExperience workExperience; public Resume() { workExperience = new WorkExperience(); } public void display() { System.out.println("姓名:" + name + ",性别:" + sex + ",年龄:" + age + "\n工作经历:" + workExperience.getWorkDate() + "," + workExperience.getCompany()); } public Object deepClone() throws IOException, ClassNotFoundException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); } // ... getter 和 setter 方法}
客户端示例:
public class PrototypeClient { public static void shallowCopy() throws CloneNotSupportedException { Resume aRes = new Resume("大鸟"); aRes.setPersonalInfo("男", "29"); aRes.setWorkExperience("1999-2002", "XX公司"); Resume bRes = (Resume) aRes.clone(); bRes.setWorkExperience("2001-2004", "YY公司"); System.out.println("浅拷贝结果:"); aRes.display(); bRes.display(); } public static void deepCopy() throws CloneNotSupportedException, IOException, ClassNotFoundException { Resume aRes = new Resume("大鸟"); aRes.setPersonalInfo("男", "29"); aRes.setWorkExperience("1999-2002", "XX公司"); Resume bRes = (Resume) aRes.deepClone(); bRes.setWorkExperience("2001-2004", "YY公司"); Resume cRes = (Resume) aRes.deepClone(); cRes.setWorkExperience("2003-2006", "ZZ公司"); System.out.println("深拷贝结果:"); aRes.display(); bRes.display(); cRes.display(); } public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException { shallowCopy(); System.out.println("=================================="); deepCopy(); }}
通过上述实现,我们可以清晰地看到浅拷贝和深拷贝的效果。浅拷贝在反射或序列化时可能导致内存泄漏或共享状态的问题,而深拷贝则确保了每个对象的独立性和完整性。选择何种拷贝方式取决于具体的应用场景和业务需求。
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年05月02日 02时46分45秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
自定义Seekbar样式
2019-03-17
Hidden treasures of the Rust ecosystem
2019-03-17
【Rust投稿】从零实现消息中间件(6)-CLIENT
2019-03-17
Rust异步浅谈
2019-03-17
【Rust每周一库】sled - 嵌入式数据库
2019-03-17
【Rust日报】2020-08-01 用 Rust 重写的一系列命令行工具
2019-03-17
【Rust 日报】2020-12-05 rust-gpu 发布 v0.2
2019-03-17
man工具
2019-03-17
FoxMail 查看邮件乱码
2019-03-17
【网络加速】TensorRT7-开发指南中文_Plus版【1】
2019-03-17
SaltStack about The Top File 使用知识介绍
2019-03-17
SaltStack的多云管理解决方案——使用Salt Cloud集成管理腾讯云平台
2019-03-17
网络协议和支持(一)、uuid模块
2019-03-17
numpy.vstack
2019-03-17
numpy.frombuffer()
2019-03-17
文件结束符EOF
2019-03-17