设计模式之原型模式

来源:互联网 发布:免费统计报表软件 编辑:程序博客网 时间:2024/05/22 14:22

一,原型模式的优势

当使用New关键字实例化对象的时候,很复杂,可以考虑原型模式来实现!再则就是New对象比较耗时,克隆(clone)比较节省时间!

二,浅克隆:

//需要实现Cloneable接口 但是clone是obejct里面的函数public class Sheep implements Cloneable,Serializable {       private String sname;    private Date birthday;    @Override    protected Object clone() throws CloneNotSupportedException {        Object obj = super.clone();  //直接调用object对象的clone()方法!        return obj;    }    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;    }    public Sheep(String sname, Date birthday) {        super();        this.sname = sname;        this.birthday = birthday;    }       public Sheep() {    }   }
/** * 测试原型模式(浅克隆) */public class Client {    public static void main(String[] args) throws Exception {        Date date = new Date(12312321331L);        Sheep s1 = new Sheep("少利",date);        System.out.println(s1);        System.out.println(s1.getSname());        System.out.println(s1.getBirthday());    date.setTime(23432432423L);    System.out.println(s1.getBirthday());        Sheep s2 = (Sheep) s1.clone();        s2.setSname("多利");        System.out.println(s2);        System.out.println(s2.getSname());        System.out.println(s2.getBirthday());           }}PS:浅克隆会出现问题,如上s1与s2的date指向同一个对象。那么克隆之后,s1的date改变了,s2的date也会跟着改变,这样s1和s2就剪不断理还乱了。

三,深克隆

//测试深复制public class Sheep2 implements 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 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;    }    public Sheep2(String sname, Date birthday) {        super();        this.sname = sname;        this.birthday = birthday;    }       public Sheep2() {    }   }
//测试:public class Client2 {    public static void main(String[] args) throws CloneNotSupportedException {        Date date = new Date(12312321331L);        Sheep2 s1 = new Sheep2("少利",date);        Sheep2 s2 = (Sheep2) s1.clone();   //实现深复制。s2对象的birthday是一个新对象!             System.out.println(s1);        System.out.println(s1.getSname());        System.out.println(s1.getBirthday());        date.setTime(23432432423L);        System.out.println(s1.getBirthday());               s2.setSname("多利");        System.out.println(s2);        System.out.println(s2.getSname());        System.out.println(s2.getBirthday());           }}

四,深克隆的另一种实现方式,序列化和反序列化实现:

/** * 原型模式(深复制,使用序列化和反序列化的方式实现深复制) * */public class Client3 {    public static void main(String[] args) throws CloneNotSupportedException, Exception {        Date date = new Date(12312321331L);        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(23432432423L);        System.out.println(s1.getBirthday());        s2.setSname("多利");        System.out.println(s2);        System.out.println(s2.getSname());        System.out.println(s2.getBirthday());           }}
//测试new与clone的时间:/** * 测试普通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;    }   }
0 0