java设计模式(创建型模式)之原型模式prototype

原型模式:

通过产生一个对象需要非常复杂的数据准备或访问权限.则可以使用原型模式
java中的克隆技术,以某个对象为原型,复制出新的对象,
优势:效率高(直接克隆,避免了重复执行构造过程)
克隆类似于new,但是不同于new.new创建新对象属性采用的是默认值,克隆对象的属性值完全和原型对象相同.并且克隆出的新对象改变不会影响原型对象再修改克隆的值.

原型模式实现

Cloneable接口和clone方法
Prototype模式中实现起来困难(内存复制操作),java中有clone方法做了绝大部分事情

案列:
1. 实现接口,重写clone方法

/**
 * 实现克隆接口:
 *          空接口
 * @author xzb_l
 *
 */
public class Sheep implements Cloneable{
    private String sname;
    private Date birthday;

    // 实现克隆重写
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object object = super.clone(); // 直接调用Object的clone方法



        // 添加以下代码,实现深复制
        Sheep s = (Sheep)object;
        // 克隆该对象下的属性..
        s.birthday = (Date)this.birthday.clone();

        return object;
    }

    public Sheep() {
        // TODO Auto-generated constructor stub
    }

    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;
    }

}

2.浅复制(没有完全复制属性)

**
 * 测试原型模式(浅克隆)--对于date对象只是克隆了地址
 * @author xzb_l
 *
 */
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Date  date = new Date(123123123123L);
        Sheep s1 = new Sheep("少利",date);
        System.out.println(s1);

        // 克隆
        Sheep s2 = (Sheep) s1.clone();
        System.out.println(s2);

        System.out.println(s1 == s2);
        System.out.println(s1.getSname()+"===="+ s2.getSname());
        s2.setSname("多利");
        System.out.println(s2.getSname());

    }
}

3.深复制

/**
 * 原型模式(深复制)
 * @author xzb_l
 *
 */
public class Client2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Date  date = new Date(123123123123L);
        Sheep s1 = new Sheep("少利",date);
        System.out.println(s1);

        // 深复制
        Sheep s2 = (Sheep) s1.clone();
        // 此时会把时间对象也克隆过来
        s1.setBirthday(new Date());
        System.out.println(s1.getBirthday());
        System.out.println(s2.getBirthday());

    }
}

序列化和发序列化实现深复制

/**
 * 使用序列化和反序列化实现深复制
 * @author xzb_l
 *
 */
public class Client3 {
    public static void main(String[] args) throws CloneNotSupportedException, Exception {
        Date  date = new Date(123123123123L);
        Sheep s1 = new Sheep("少利",date);
        System.out.println(s1);

        // 深复制
        //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();
        date.setTime(2222111111L); // 时间属性对象更改
        System.out.println(s1 == s2);// false s1.date != s2.date



    }
}

普通方式new 和clone方式创建对象的效率差异

/**
 * 测试普通new方式和clone方式创建对象的效率差异
 * 如果需要短时间创建大量对象并且new的过程比较耗时,
 * 则可以考虑使用原型模式
 * @author xzb_l
 *
 */
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("普通方式创建对象耗时:" + (end-start));
    }

    public static void testClone(int size) throws Exception{
        long start = System.currentTimeMillis();
        Laptop t = new Laptop();
        for (int i=0; i < size; i++) {
            Laptop t1 = (Laptop) t.clone();
        }
        long end = System.currentTimeMillis();
        System.out.println("普通方式创建对象耗时:" + (end-start));
    }
    public static void main(String[] args) throws Exception {
        testNew(1000);
        testClone(1000);
        /*普通方式创建对象耗时:11123
        普通方式创建对象耗时:11*/
    }
}

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 {
            // TODO Auto-generated method stub
            return super.clone();
        }
}

猜你喜欢

转载自blog.csdn.net/qq_34898847/article/details/82666719