java设计模式 GOF23 04 原型模式

一.原型模式介绍

  因为java中new一个新对象比clone一个对象需要花费等多的资源,所以一般需要

在短时间内创建大量对象并且new对象的过程需要耗费比较多的资源使用原型模式。

 

想要clone一个类需要这个类实现Cloneable接口,重载clone方法,这个接口在底层

通过内存拷贝实现clone对象,因此效率很高。

 

package com.lz.prototype; import java.util.Date; public class ShallowClone implements Cloneable{ private String name; private int age; private Date date; public ShallowClone() { } public ShallowClone(String name, int age, Date date) { super(); this.name = name; this.age = age; this.date = date; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } @Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone(); return obj; } }
package com.lz.prototype; import java.util.Date; public class ShallowTest { public static void main(String[] args) { ShallowClone sc1 = new ShallowClone("laro", 20, new Date()); System.out.println(sc1); System.out.println(sc1.getName()); System.out.println(sc1.getAge()); System.out.println(sc1.getDate()); ShallowClone sc2 = null; try { sc2 = (ShallowClone) sc1.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } sc1.setDate(new Date()); System.out.println(sc2); System.out.println(sc2.getName()); System.out.println(sc2.getAge()); System.out.println(sc2.getDate()); } }

二.原型模式效率检测

下面是一个简单的效率测试

package com.lz.prototype; 
public class Efficiency { public static void main(String[] args) throws CloneNotSupportedException { test01(); T s = new T(); test02(s); } public static void test01() { long start = System.currentTimeMillis(); for ( int i=0; i<1000; i++ ) { T s = new T(); } long end = System.currentTimeMillis(); System.out.println((end-start)+"毫秒"); } public static void test02(T s) throws CloneNotSupportedException { long start = System.currentTimeMillis(); for ( int i=0; i<1000; i++ ) { T copy = (T) s.clone(); } long end = System.currentTimeMillis(); System.out.println((end-start)+"毫秒"); } } class T implements Cloneable{ public T() { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }

 

三.浅拷贝与深拷贝

下面是一个简单代码实现当然上面的代码只实现了浅拷贝,浅拷贝的含义是只clone这个对象本身,而这个类里面包含的其他引用对象并没有

实现clone。这里想要实现深拷贝需要改动代码

package com.lz.prototype;

import java.util.Date;

public class DeepClone implements Cloneable{
    private String name;
    private int age;
    private Date date;
    public DeepClone() {
    }
    
    public DeepClone(String name, int age, Date date) {
        super();
        this.name = name;
        this.age = age;
        this.date = date;
    }
    

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getDate() {
        return date;
    }

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

    /*
     * 实现深拷贝
     * @see java.lang.Object#clone()
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();
        DeepClone dc = (DeepClone) obj;
        dc.date = (Date) this.date.clone();
        return obj;
    }
}

简单的实现深clone很简单,只需要将需要clone的类的内部的引用类也clone即可。

但是这种方法在比较复杂的类中就不容易实现了,这里还可以使用序列化和反序列化实现clone

当然一个类想实现序列化和反序列话需要实现Serializable接口

下面是一个简单的代码实现:

 

package com.lz.prototype;

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

/*
 * 序列化反序列化clone对象
 */
public class Test01 {
    public static void main(String[] args) throws Exception {
        Sheep s1 = new Sheep("tom", new Date(1000000000L));
        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("测试前");
        System.out.println(s1);
        System.out.println(s1.getName()+" " + s1.getBirthday());
        System.out.println(s2);
        System.out.println(s2.getName()+" " + s2.getBirthday());
        
        s1.setName("laro");
        s1.setBirthday(new Date(1000000000L));
        
        System.out.println("测试后");
        System.out.println(s1);
        System.out.println(s1.getName()+" " + s1.getBirthday());
        System.out.println(s2);
        System.out.println(s2.getName()+" " + s2.getBirthday());
    }
}


class Sheep implements Cloneable, Serializable{
    private String name;
    private Date birthday;
    public Sheep() {
    }
    public Sheep(String name, Date birthday) {
        super();
        this.name = name;
        this.birthday = birthday;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

 

你可能感兴趣的:(java设计模式 GOF23 04 原型模式)