设计模式-原型模式实例-02-深克隆

设计模式-原型模式实例-深克隆

浅克隆与深克隆:

浅克隆:

当对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量未被复制。(Object.clone()方法)

深克隆:

对象本身及其包含的所有成员变量也将被复制。

序列化,通过序列化对象将对象写到一个流中,再从流中读出来。原型必须实现Serializable接口(空接口/标识接口),才能序列化。)

注意:

x.clone() != x; //克隆对象和原型并非同一对象。

x.clone().getClass() == x.getClass(); //克隆对象与原对象类型一样。

如果equals()定义恰当,x.clone().equals(x);

要点:

当需要创建大量相同或相似对象时,可通过对一个已有对象的复制获取更多的对象(克隆/复制)。

通过克隆方法所创建的对象是全新的对象,拥有新的内存地址,是独立的。

优点:

简化对象创建过程,提高创建效率;

扩展性好;

简化创建结构,无须专门的工厂类;

可使用深克隆,保存对象状态,以便在需要的时候使用,可辅助实现撤销操作。

缺点:

每一个类需要一个克隆方法,对已有类改造时需修改源代码,违背开闭原则;

深克隆需编写一个较为复杂的代码。

适用环境:

创建新对象成本较大;

系统要保存对象的状态,而对象的状态变化很小;

避免使用分层次的工厂类创建分层次的对象。

 

实例1:邮件克隆(深克隆)。

类图

 

代码实现:

代码结构:

 

 Email.java:

import java.io.*;

//具体原型类
public class Email implements Serializable {
    private Attachment attachment = null;

    public Email(){
        this.attachment = new PrototypePattern.Attachment();
    }

    public Object deepClone() throws IOException,ClassNotFoundException, OptionalDataException{
        //将对象写入流中
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bao);
        oos.writeObject(this);

        //将对象从流中取出
        ByteArrayInputStream bis = new ByteArrayInputStream((bao.toByteArray()));
        ObjectInputStream ois = new ObjectInputStream(bis);
        return(ois.readObject());
    }

    public Attachment getAttachment(){
        return this.attachment;
    }
    public void display(){
        System.out.println("read the email");
    }
}

 

Attachment.java:

import java.io.Serializable;

//附件类
public class Attachment implements Serializable {
    public void download(){
        System.out.println("download the fuemail");
    }
}

 

Client.java:

public class Client {
    public static void main(String[] args) {
        Email email,copyEmail = null;
        email = new Email();
        try {
            copyEmail = (Email) email.deepClone();
        }catch (Exception e){
            e.printStackTrace();
        }

        System.out.println("email == copyEmail?");
        System.out.println(email == copyEmail);
        System.out.println("email.getAttachment == copyEmail.getAttachment?");
        System.out.println(email.getAttachment() == copyEmail.getAttachment());
    }
}

 

 

 

结论:

深克隆通过写入流和写出流(Serializable),将其成员变量也克隆了一份。



 
posted @ 2022-03-12 16:58  临易  阅读(84)  评论(0编辑  收藏  举报