博客
关于我
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/

你可能感兴趣的文章
mysql client library_MySQL数据库之zabbix3.x安装出现“configure: error: Not found mysqlclient library”的解决办法...
查看>>
MySQL Cluster 7.0.36 发布
查看>>
Multimodal Unsupervised Image-to-Image Translation多通道无监督图像翻译
查看>>
MySQL Cluster与MGR集群实战
查看>>
multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
查看>>
mysql cmake 报错,MySQL云服务器应用及cmake报错解决办法
查看>>
Multiple websites on single instance of IIS
查看>>
mysql CONCAT()函数拼接有NULL
查看>>
multiprocessing.Manager 嵌套共享对象不适用于队列
查看>>
multiprocessing.pool.map 和带有两个参数的函数
查看>>
MYSQL CONCAT函数
查看>>
multiprocessing.Pool:map_async 和 imap 有什么区别?
查看>>
MySQL Connector/Net 句柄泄露
查看>>
multiprocessor(中)
查看>>
mysql CPU使用率过高的一次处理经历
查看>>
Multisim中555定时器使用技巧
查看>>
MySQL CRUD 数据表基础操作实战
查看>>
multisim变压器反馈式_穿过隔离栅供电:认识隔离式直流/ 直流偏置电源
查看>>
mysql csv import meets charset
查看>>
multivariate_normal TypeError: ufunc ‘add‘ output (typecode ‘O‘) could not be coerced to provided……
查看>>