java设计模式 GOF23 04 原型模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 原型模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之GOF23原型模式02

原型模式(GOF23)

一起来学GOF23种设计模式

Gof设计模式之原型模式

GOF23设计模式之单例模式

GOF23汇总