设计模式——原型模式(Prototype)(浅克隆、深克隆)

代码:GitHub

原型设计模式(克隆一个苹果)

0. UML结构图

在这里插入图片描述

1. Code 克隆用的Apple类

1.1 苹果基类

import java.util.Date;

/**
 * 苹果基类(不是必须写)
 *
 * @author ALion
 * @version 2019/1/28 22:56
 */
public class Apple implements Cloneable {

    protected int size;

    protected String place;

    protected Date manufacture;

    public Apple(int size, String place, Date manufacture) {
        this.size = size;
        this.place = place;
        this.manufacture = manufacture;
    }

}

1.2 可克隆的苹果(用于浅克隆)

import java.util.Date;

/**
 * 可克隆的苹果(浅克隆)
 * <p>
 *     1.需要实现Cloneable接口
 *     2.覆写Object的clone方法
 * </p>
 *
 * @author ALion
 * @version 2019/1/28 22:21
 */
public class ShallowApple extends Apple {


    public ShallowApple(int size, String place, Date manufacture) {
        super(size, place, manufacture);
    }

    @Override
    protected ShallowApple clone() throws CloneNotSupportedException {
        // clone是native方法,直接调用C代码,效率高
        return (ShallowApple) super.clone();
    }

}

1.3 可克隆的苹果(用于深克隆)

import java.util.Date;

/**
 * 可克隆的苹果(深克隆)
 * <p>
 *     1.需要实现Cloneable接口
 *     2.覆写Object的clone方法,同时把属性也克隆
 * </p>
 *
 * @author ALion
 * @version 2019/1/28 22:21
 */
public class DeepApple extends Apple {


    public DeepApple(int size, String place, Date manufacture) {
        super(size, place, manufacture);
    }

    @Override
    protected DeepApple clone() throws CloneNotSupportedException {
        // clone是native方法,直接调用C代码,效率高
        DeepApple apple = (DeepApple) super.clone();
        // 深克隆需要同时把属性对象也克隆
        apple.manufacture = (Date) this.manufacture.clone();
        return apple;
    }
}

1.4 可序列化的苹果(用于深克隆)

import java.io.Serializable;
import java.util.Date;

/**
 * 可序列化的苹果(深克隆)
 *
 * @author ALion
 * @version 2019/1/28 22:21
 */
public class SerializableApple implements Serializable {

    public int size;

    public String place;

    public Date manufacture;

    public SerializableApple(int size, String place, Date manufacture) {
        this.size = size;
        this.place = place;
        this.manufacture = manufacture;
    }

}

1.5 家庭作业类(用于测试原型模式性能)

/**
 * 家庭作业类(用于测试原型模式性能)
 * <p>
 *     1.自己做家庭作业很慢
 *     2.直接抄(克隆)别人的很快
 * </p>
 *
 * @author ALion
 * @version 2019/1/28 23:37
 */
public class Homework implements Cloneable{

    public Homework() {
        try {
            // 完成家庭作业需要一定时间
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected Homework clone() throws CloneNotSupportedException {
        return (Homework) super.clone();
    }
}

2. 克隆Test

2.1 浅克隆测试

import java.util.Date;

/**
 * 浅克隆测试
 *
 * @author ALion
 * @version 2019/1/28 23:12
 */
public class ShallowCloneTest {


    public static void main(String[] args) throws CloneNotSupportedException {
        System.out.println("------+--浅克隆Test--+------");

        ShallowApple apple = new ShallowApple(10, "China", new Date());

        print(apple);

        System.out.println("------+------+------");

        ShallowApple cloneApple = apple.clone();

        print(cloneApple);

        System.out.println("修改manufacture");
        apple.manufacture.setTime(10000000000L);
        System.out.println("apple.manufacture = " + apple.manufacture);
        System.out.println("cloneApple.manufacture = " + cloneApple.manufacture);
    }

    private static void print(Apple apple) {
        System.out.println("apple = " + apple);
        System.out.println("apple.size = " + apple.size);
        System.out.println("apple.place = " + apple.place);
        System.out.println("apple.manufacture = " + apple.manufacture);
    }

}

2.2 深克隆测试

import java.util.Date;

/**
 * 深克隆测试
 *
 * @author ALion
 * @version 2019/1/28 22:32
 */
public class DeepCloneTest {

    public static void main(String[] args) throws CloneNotSupportedException {
        System.out.println("------+--深克隆Test--+------");

        DeepApple apple = new DeepApple(10, "China", new Date());

        print(apple);

        System.out.println("------+------+------");

        DeepApple cloneApple = apple.clone();

        print(cloneApple);

        System.out.println("修改manufacture");
        apple.manufacture.setTime(10000000000L);
        System.out.println("apple.manufacture = " + apple.manufacture);
        System.out.println("cloneApple.manufacture = " + cloneApple.manufacture);
    }

    private static void print(Apple apple) {
        System.out.println("apple = " + apple);
        System.out.println("apple.size = " + apple.size);
        System.out.println("apple.place = " + apple.place);
        System.out.println("apple.manufacture = " + apple.manufacture);
    }

}

2.3 序列化、反序列化的方式实现深克隆 测试

import java.io.*;
import java.util.Date;

/**
 * 序列化、反序列化的方式实现深克隆 测试
 *
 * @author ALion
 * @version 2019/1/28 23:20
 */
public class SerializableCloneTest {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        System.out.println("------+--深克隆Test--+------");

        SerializableApple apple = new SerializableApple(10, "China", new Date());

        print(apple);

        System.out.println("------+------+------");

        // 序列化
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(apple);
        byte[] bytes = bos.toByteArray();
        // 反序列化
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bis);
        SerializableApple cloneApple = (SerializableApple) ois.readObject();

        print(cloneApple);

        System.out.println("修改manufacture");
        apple.manufacture.setTime(10000000000L);
        System.out.println("apple.manufacture = " + apple.manufacture);
        System.out.println("cloneApple.manufacture = " + cloneApple.manufacture);
    }

    private static void print(SerializableApple apple) {
        System.out.println("apple = " + apple);
        System.out.println("apple.size = " + apple.size);
        System.out.println("apple.place = " + apple.place);
        System.out.println("apple.manufacture = " + apple.manufacture);
    }

}

2.4 原型模式的性能测试

  • 注: new生成对象太慢时or同时间需要创建大量相同对象时,就使用原型模式
/**
 * 原型模式的性能测试
 * <p>
 *     new生成对象太慢时or同时间需要创建大量相同对象时,就使用原型模式
 * </p>
 *
 * @author ALion
 * @version 2019/1/28 23:34
 */
public class PerformanceTest {

    public static void main(String[] args) throws CloneNotSupportedException {
        // 直接做家庭作业
        doHomework();

        // 抄(克隆)他人的作业
        cloneHomework();
    }

    public static void doHomework() {
        long start = System.currentTimeMillis();

        Homework homework = new Homework();
        for (int i = 0; i < 100; i++) {
            Homework homework2 = new Homework();
            System.out.println("do homework = " + i);
        }

        long end = System.currentTimeMillis();
        System.out.println("PerformanceTest.doHomework: 耗时" + (end - start) + "毫秒");
    }

    public static void cloneHomework() throws CloneNotSupportedException {
        long start = System.currentTimeMillis();

        Homework homework = new Homework();
        for (int i = 0; i < 100; i++) {
            Homework homework2 = homework.clone();
            System.out.println("clone homework = " + i);
        }

        long end = System.currentTimeMillis();
        System.out.println("PerformanceTest.cloneHomework: 耗时" + (end - start) + "毫秒");
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值