一. 定义

  • 当需要创建大量相同或相似对象时,且对象的创建过程较为复杂,可以只创建一个对象,然后再通过克隆的方式复制出多个相同的对象。

浅克隆:被复制对象的所有普通成员变量都具有与原来对象相同的值,而所有的对其他对象的引用扔指向原来的对象,即属性是引用对象不复制。

深克隆:被复制对象的所有普通成员变量都具有与原来对象相同的值,而所有的对其他对象的引用扔指向新的对象,即属性是引用对象复制。


二. 模式结构

uTools_1687526954894.png

1. Prototype(抽象原型类)

  • 抽象原型类是定义具体克隆自己方法的接口,是所有具体原型的公共父类,可以是抽象类,也可以是接口。

2. ConcretePrototype(具体原型类)

  • 具体原型类实现具体的克隆方法,在克隆方法中返回自己的一个克隆对象。

三. 实例

1. 浅克隆

uTools_1687527623062.png

①Attachment

public class Attachment {

    public void download(){
        System.out.println("下载附件");
    }
}

②Email

public class Email implements Cloneable{
    private Attachment attachment=null;

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

    public Attachment getAttachment() {
        return attachment;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Email clone=(Email) super.clone();
        return clone;
    }
}

3. 深克隆

序列化是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象扔存在于内存,所以可以通过序列化实现深克隆。 uTools_1687529616117.png

①Attachment

import java.io.Serializable;

public class Attachment implements Serializable {

    public void download(){
        System.out.println("下载附件");
    }
}

②Email

import java.io.*;

public class Email implements Serializable{
    private Attachment attachment=null;

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

    public Attachment getAttachment() {
        return attachment;
    }

    public Object deepClone() throws IOException, ClassNotFoundException {

        //将对象写入流中
        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 void display() {
        System.out.println("查看邮件");
    }
}

4. Client

public class Client
{
    public static void main(String[] args) throws Exception
    {
        Email email, copyEmail;
        email=new Email();
        copyEmail= (Email) email.clone();

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