设计模式之原型模式 Prototype

public class Sheep implements Cloneable,Serializable{
    
    private String sname;
    private Date birthday;
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();    
        return obj;
    }

    public Sheep(String sname, Date birthday) {
        super();
        this.sname = sname;
        this.birthday = birthday;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    
}
sheep类
public class Sheep2 implements Cloneable{
    
    private String sname;
    private Date birthday;
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();
        
        //添加如下代码实现深克隆
        Sheep2 s = (Sheep2) obj;
        s.birthday = (Date) this.birthday.clone();  //把属性也进行克隆
        
        return obj;
    }

    public Sheep2(String sname, Date birthday) {
        super();
        this.sname = sname;
        this.birthday = birthday;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    
    

}
sheep2类
/**
 * 测试原型模式--浅克隆
 * @author bzhx
 * 2017年3月10日
 */
public class Client {

    public static void main(String[] args) throws CloneNotSupportedException {
        Date date = new Date(125545225555L);
        Sheep s1  = new Sheep("少利",date);
        
        
        System.out.println("测试浅复制");
        System.out.println(s1);
        System.out.println(s1.getSname());
        System.out.println(s1.getBirthday());
        
        date.setTime(5586558657741L);
        System.out.println(s1.getBirthday());
        
        Sheep s2 = (Sheep) s1.clone();
        s2.setSname("少少利");   //clone后的新对象还可以修改
        System.out.println(s2);  //clone对象不一样
        System.out.println(s2.getSname()); //但是clone后的内容一致
        System.out.println(s2.getBirthday());
    }

}
测试浅克隆
/**
 * 原型模式(深克隆)
 * @author bzhx
 * 2017年3月10日
 */
public class Client2 {

    public static void main(String[] args) throws CloneNotSupportedException {
        Date date = new Date(125545225555L);
        
        Sheep2 s1  = new Sheep2("少利",date);
        Sheep2 s2 = (Sheep2) s1.clone(); //实现深复制
        
        System.out.println("测试深复制");
        System.out.println(s1);
        System.out.println(s1.getSname());
        System.out.println(s1.getBirthday());
        
        date.setTime(5586558657741L);
        System.out.println(s1.getBirthday());
        
        
        s2.setSname("少少利");   //clone后的新对象还可以修改
        System.out.println(s2);  //clone对象不一样
        System.out.println(s2.getSname()); //但是clone后的内容一致
        System.out.println(s2.getBirthday());
    }
}
测试深克隆
public class Client3 {

    public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
        
        Date date = new Date(125545225555L);
        Sheep s1  = new Sheep("少利",date);
        
        System.out.println(s1);
        System.out.println(s1.getSname());
        System.out.println(s1.getBirthday());
        
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        
        oos.writeObject(s1);
        byte[] bytes = bos.toByteArray();
        
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream  ois = new ObjectInputStream(bis);
        
        Sheep s2 = (Sheep) ois.readObject(); //克隆好的对象
        
        System.out.println("修改原型对象的属性值");
        date.setTime(5586558657741L);
        System.out.println(s1.getBirthday());
        
        
        s2.setSname("少少利");   //clone后的新对象还可以修改
        System.out.println(s2);  //clone对象不一样
        System.out.println(s2.getSname()); //但是clone后的内容一致
        System.out.println(s2.getBirthday());

    }

}
深复制,使用序列化和反序列化的方式实现深复制
/**
 * 测试普通new方式创建对象和clone方式创建对象的效率差异
 * 如果需要短时间创建大量对象,并且new的过程比较耗时,则可以考虑使用原型模式
 * @author bzhx
 * 2017年3月10日
 */

public class Client4 {
    
    //new创建对象
    public static void testNew(int size){
        long start = System.currentTimeMillis();
        for (int i = 0; i < size; i++) {
            Laptop t = new Laptop();
        }
        long end = System.currentTimeMillis();
        System.out.println("new的方式创建耗时:" + (end-start));
    }
    
    //clone创建
    public static void testClone(int size) throws CloneNotSupportedException{
        long start = System.currentTimeMillis();
        Laptop t = new Laptop();
        for (int i = 0; i < size; i++) {
            Laptop temp = (Laptop) t.clone();
        }
        long end = System.currentTimeMillis();
        System.out.println("Clone的方式创建耗时:" + (end-start));
    }

    public static void main(String[] args) throws Exception {
        testNew(1000);
        testClone(1000);
    }

}

class Laptop implements Cloneable{
    
    public Laptop(){
        try {
            Thread.sleep(10);  //模拟创建对象耗时的过程
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();    
        return obj;
    }
}
测试普通new方式创建对象和clone方式创建对象的效率差异

深复制(深克隆)与浅复制(浅克隆)

⑴浅复制(浅克隆) 

    被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。 

⑵深复制(深克隆) 

    被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。 

 

转载于:https://www.cnblogs.com/qingdaofu/p/7466310.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值