【GOF23设计模式】_原型模式JAVA233-234

来源:互联网 发布:mac系统如何复制到u盘 编辑:程序博客网 时间:2024/05/18 15:24

来源:http://www.bjsxt.com/
一、S03E233_01【GOF23设计模式】_原型模式、prototype、浅复制、深复制、Cloneable接口
原型模式

浅复制

package com.test.prototype;import java.util.Date;/** * 浅复制 */public class Sheep implements Cloneable{//Cloneable为标记接口    private String sname;    private Date birthday;    @Override    protected Object clone() throws CloneNotSupportedException {        Object obj = super.clone();//直接调用object对象的clone()方法        return obj;    }    public Sheep() {    }    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;    }}
package com.test.prototype;import java.util.Date;/** * 测试原型模式(浅复制) */public class Client {    public static void main(String[] args) throws Exception {        Date date = new Date(3333332323L);        Sheep s1 = new Sheep("少利", date);        Sheep s2 = (Sheep) s1.clone();        System.out.println(s1);        System.out.println(s1.getSname());        System.out.println(s1.getBirthday());        date.setTime(332324355555555L);//浅复制:s1和s2指向同一date对象的地址,一改全改        System.out.println(s1.getBirthday());//s1.getBirthday() == s2.getBirthday()        s2.setSname("多利");        System.out.println(s2);        System.out.println(s2.getSname());        System.out.println(s2.getBirthday());    }}

控制台输出:s1修改时间后,s2的也跟着改(Fri Dec 10 00:59:15 CST 12500)

com.test.prototype.Sheep@1db9742少利Sun Feb 08 21:55:32 CST 1970Fri Dec 10 00:59:15 CST 12500com.test.prototype.Sheep@647e05多利Fri Dec 10 00:59:15 CST 12500

深复制

package com.test.prototype;import java.util.Date;/** * 深复制 */public class Sheep2 implements Cloneable{//Cloneable为标记接口    private String sname;    private Date birthday;    @Override    protected Object clone() throws CloneNotSupportedException {        Object obj = super.clone();//直接调用object对象的clone()方法        //添加如下代码实现深复制(Deep Clone)        Sheep2 s = (Sheep2) obj;        s.birthday = (Date) this.birthday.clone();//属性克隆!        return obj;    }    public Sheep2() {    }    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;    }}
package com.test.prototype;import java.util.Date;/** * 测试原型模式(深复制) */public class Client2 {    public static void main(String[] args) throws Exception {        Date date = new Date(3333332323L);        Sheep2 s1 = new Sheep2("少利", date);        Sheep2 s2 = (Sheep2) s1.clone();        System.out.println(s1);        System.out.println(s1.getSname());        System.out.println(s1.getBirthday());        date.setTime(332324355555555L);//浅复制:s1和s2指向同一date对象的地址,一改全改        System.out.println(s1.getBirthday());//s1.getBirthday() == s2.getBirthday()        s2.setSname("多利");        System.out.println(s2);        System.out.println(s2.getSname());        System.out.println(s2.getBirthday());    }}

控制台输出:s1修改时间后,s2还是最初的(Sun Feb 08 21:55:32 CST 1970)

com.test.prototype.Sheep2@1db9742少利Sun Feb 08 21:55:32 CST 1970Fri Dec 10 00:59:15 CST 12500com.test.prototype.Sheep2@647e05多利Sun Feb 08 21:55:32 CST 1970

二、S03E234_01【GOF23设计模式】_原型模式、反序列化实现深复制、效率对比、创建型模式总结
利用序列化和反序列化技术实现深复制

package com.test.prototype;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.util.Date;/** * 原型模式(使用序列化和反序列化的方式实现深复制) */public class Client3 {    public static void main(String[] args) throws Exception {        Date date = new Date(3333332323L);        Sheep s1 = new Sheep("少利", date);        System.out.println(s1);        System.out.println(s1.getSname());        System.out.println(s1.getBirthday());//      Sheep s2 = (Sheep) s1.clone();        //使用序列化和反序列化实现深复制        //序列化        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(332324355555555L);        System.out.println(s1.getBirthday());        s2.setSname("多利");        System.out.println(s2);        System.out.println(s2.getSname());        System.out.println(s2.getBirthday());    }}

短时间大量创建对象时,原型模式和普通new方式效率测试:

package com.test.prototype;/** * 测试普通new方式创建对象和clone方式创建对象的效率差异! * 如果需要短时间创建大量对象,并且new的过程比较耗时,则可以考虑使用原型模式! */public class Client4 {    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));    }    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){            e.printStackTrace();        }    }    @Override    protected Object clone() throws CloneNotSupportedException {        Object obj = super.clone();//直接调用object对象的clone()方法        return obj;    }}

控制台输出:

new的方式创建耗时:10168clone的方式创建耗时:10

开发中的应用场景:
原型模式很少单独出现,一般和工厂模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。
spring中bean的创建实际就是两种:单例模式和原型模式(原型模式需要和工厂模式搭配起来)。

创建型模式的总结:
创建型模式的总结

0 0