博客
关于我
java 原型模式(大话设计模式)
阅读量:680 次
发布时间: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/

你可能感兴趣的文章
OSG学习:几何对象的绘制(四)——几何体的更新回调:旋转的线
查看>>
OSG学习:场景图形管理(一)——视图与相机
查看>>
OSG学习:场景图形管理(三)——多视图相机渲染
查看>>
OSG学习:场景图形管理(二)——单窗口多相机渲染
查看>>
OSG学习:场景图形管理(四)——多视图多窗口渲染
查看>>
OSG学习:新建C++/CLI工程并读取模型(C++/CLI)——根据OSG官方示例代码初步理解其方法
查看>>
Sql 随机更新一条数据返回更新数据的ID编号
查看>>
OSG学习:空间变换节点和开关节点示例
查看>>
OSG学习:纹理映射(一)——多重纹理映射
查看>>
OSG学习:纹理映射(七)——聚光灯
查看>>
OSG学习:纹理映射(三)——立方图纹理映射
查看>>
OSG学习:纹理映射(二)——一维/二维/简单立方图纹理映射
查看>>
OSG学习:纹理映射(五)——计算纹理坐标
查看>>
OSG学习:纹理映射(六)——灯光
查看>>
OSG学习:纹理映射(四)——三维纹理映射
查看>>
OSG:从源码看Viewer::run() 一
查看>>
OSI七层模型与TCP/IP四层与五层模型详解
查看>>
OSI七层模型的TCP/IP模型都有哪几层和他们的对应关系?
查看>>
OSM数据如何下载使用(地图数据篇.11)
查看>>
OSPF 四种设备角色:IR、ABR、BR、ASBR
查看>>