博客
关于我
java 原型模式(大话设计模式)
阅读量:666 次
发布时间:2019-03-16

本文共 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();    }}

通过上述实现,我们可以清晰地看到浅拷贝和深拷贝的效果。浅拷贝在反射或序列化时可能导致内存泄漏或共享状态的问题,而深拷贝则确保了每个对象的独立性和完整性。选择何种拷贝方式取决于具体的应用场景和业务需求。

转载地址:http://ezmqz.baihongyu.com/

你可能感兴趣的文章
输出对象的值——踩坑
查看>>
angular2项目里使用排他思想
查看>>
折线图上放面积并隐藏XY轴的线
查看>>
zabbix之自动发现
查看>>
Experience of tecent interview
查看>>
failed to push some refs to git
查看>>
在苹果Mac上如何更改AirDrop名称?
查看>>
1110 Complete Binary Tree (25 point(s))
查看>>
541【毕设课设】基于单片机电阻电感电容RLC测量仪系统
查看>>
568【毕设课设】基于单片机多路温度采集显示报警控制系统设计
查看>>
基于8086交通灯系统仿真设计(微机原理设计资料)
查看>>
解读域名管理之:域名注册机构介绍
查看>>
找中位数
查看>>
这些运维发展方向及系统运维技能都不了解,怎么能吃透Linux??
查看>>
自动化测试——UI自动化测试的痛点
查看>>
如何将萌推商品主图、属性图、详情图批量保存到电脑的方法
查看>>
2021年N1叉车司机模拟考试及N1叉车司机考试软件
查看>>
【奇淫巧技】Java动态代理(JDK和cglib)
查看>>
2021-05-11 现代操作系统 《现代操作系统 第4版》第3章 内存管理——总结(分段,分页,段页)(转载)
查看>>
MP4修改元数据日志记录
查看>>