原型模式

思想

将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。

浅克隆

package com.principle.prototype;

import java.util.Date;

public class Prototype implements Cloneable {
    
    private int temp;
    private Date date;
    
    public int getTemp() {
        return temp;
    }

    public void setTemp(int temp) {
        this.temp = temp;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    protected Object clone() throws CloneNotSupportedException {
        Prototype prototype = (Prototype) super.clone();
        return prototype;
    };
    
    public static void main(String[] args) throws CloneNotSupportedException {
        Prototype prototype=new Prototype();
        prototype.setTemp(19);
        Date date=new Date(212121121L);
        prototype.setDate(date);
        Prototype prototype2=(Prototype) prototype.clone();
        
        System.out.println(prototype);
        System.out.println(prototype.getTemp());
        System.out.println(prototype.getDate());
        System.out.println(prototype2);
        System.out.println(prototype2.getTemp());
        System.out.println(prototype2.getDate());
        
        prototype.setTemp(12);
        date.setTime(1212121212);
        System.out.println(prototype.getDate());
        System.out.println(prototype2.getDate());
        
        System.out.println(prototype.getTemp());
        System.out.println(prototype2.getTemp());
    }

}
打印结果:
com.principle.prototype.Prototype@15db9742
19
Sat Jan 03 18:55:21 CST 1970
com.principle.prototype.Prototype@5c647e05
19
Sat Jan 03 18:55:21 CST 1970
Thu Jan 15 08:42:01 CST 1970
Thu Jan 15 08:42:01 CST 1970
12
19

可以看出,如果参数是对象类型,修改值后,克隆的属性值也跟着改变;如果是基本类型就不变了;说明在浅克隆中,对象属性克隆的是引用地址,他们引用的还是同一个对象。

深克隆:

package com.principle.prototype;

import java.util.Date;

public class Prototype3 implements Cloneable {
    
    private int temp;
    private Date date;
    
    public int getTemp() {
        return temp;
    }

    public void setTemp(int temp) {
        this.temp = temp;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    protected Object clone() throws CloneNotSupportedException {
        Prototype3 prototype = (Prototype3) super.clone();
        prototype.date=(Date) this.date.clone();
        return prototype;
    };
    
    public static void main(String[] args) throws CloneNotSupportedException {
        Prototype3 prototype=new Prototype3();
        prototype.setTemp(19);
        Date date=new Date(212121121L);
        prototype.setDate(date);
        //修改代码
        Prototype3 prototype2=(Prototype3) prototype.clone();
        
        System.out.println(prototype);
        System.out.println(prototype.getTemp());
        System.out.println(prototype.getDate());
        System.out.println(prototype2);
        System.out.println(prototype2.getTemp());
        System.out.println(prototype2.getDate());
        
        prototype.setTemp(12);
        date.setTime(1212121212);
        System.out.println(prototype.getDate());
        System.out.println(prototype2.getDate());
        
        System.out.println(prototype.getTemp());
        System.out.println(prototype2.getTemp());
    }

}
打印结果:
com.principle.prototype.Prototype3@15db9742
19
Sat Jan 03 18:55:21 CST 1970
com.principle.prototype.Prototype3@5c647e05
19
Sat Jan 03 18:55:21 CST 1970
Thu Jan 15 08:42:01 CST 1970
Sat Jan 03 18:55:21 CST 1970
12
19

可以看出,只是修改了一小部分,就是在克隆的代码中,对对象也进行了克隆处理,这样就不是同一个引用地址,而是各自的新对象。

通过序列化和反序列化来实现深复制

package com.principle.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

public class Prototype3 implements Cloneable,Serializable {
    
    private int temp;
    private Date date;
    
    public int getTemp() {
        return temp;
    }

    public void setTemp(int temp) {
        this.temp = temp;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    protected Object clone() throws CloneNotSupportedException {
        Prototype3 prototype = (Prototype3) super.clone();
        prototype.date=(Date) this.date.clone();
        return prototype;
    };
    
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        Prototype3 prototype=new Prototype3();
        prototype.setTemp(19);
        Date date=new Date(212121121L);
        prototype.setDate(date);
        System.out.println(prototype);
        System.out.println(prototype.getTemp());
        System.out.println(prototype.getDate());
        //修改代码
        //使用序列化和反序列化实现深复制
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(bos);
        oos.writeObject(prototype);
        byte[] bytes=bos.toByteArray();
        
        ByteArrayInputStream bis=new ByteArrayInputStream(bytes);
        ObjectInputStream ois=new ObjectInputStream(bis);
        
        Prototype3 p3=(Prototype3) ois.readObject();
        
        System.out.println("修改原型对象的属性值");
        date.setTime(2343234L);
        
        System.out.println(prototype.getDate());
        
        p3.setTemp(22);
        System.out.println(p3);
        System.out.println(p3.getTemp());
        System.out.println(p3.getDate());
    }
}

打印结果:
com.principle.prototype.Prototype3@15db9742
19
Sat Jan 03 18:55:21 CST 1970
修改原型对象的属性值
Thu Jan 01 08:39:03 CST 1970
com.principle.prototype.Prototype3@28d93b30
22
Sat Jan 03 18:55:21 CST 1970

通过序列化和反序列化后就会重新生成一个新的对象

当new一个对象比较耗时的时候,就可以用原型模式来实例化对象。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容