Java设计模式之原型模式

Java设计模式之原型模式

原型模式属于创建型模式,原型模式用于直接创建一个对象代价比较大时使用,通过拷贝原型创建新的对象。一般情况,原型模式和工厂模式一起出现,很少单独出现。

一、原型模式的两种实现

(1):实现Cloneable,重写clone()方法(浅拷贝)
(2):实现Serializable ,读取二进制流(深拷贝)

二、原型模式浅拷贝UML类图

在这里插入图片描述

三、原型模式深拷贝UML类图

在这里插入图片描述

浅拷贝和深拷贝的基本介绍

浅拷贝:

  • 对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递。 基本类型的拷贝,其中一个对象修改了该值,不会影响另外一个。
  • 对于数据类型是引用类型的成员变量,浅拷贝会进行引用传递。浅拷贝会把内存地址赋值给成员变量,他们指向同一个内存空间,改变其中的一个值,会影响另一个。

深拷贝:

  • 对于数据类型是基本数据类型的成员变量时,深拷贝也会直接进行值传递,基本类型的拷贝,其中一个对象修改了该值,不会影响另外一个。
  • 对于数据类型是引用类型的成员变量,深拷贝会拷贝整个对象,指向不同内存空间,改变其中一个,不会对另一个产生影响。
  • 对于多层对象拷贝,需要实现Cloneable 并重写 clone() 方法,实现对象的层层拷贝。

第一种: 实现Cloneable,重写clone()方法

/**
 * @author yly
 * @ClassName Sheep
 * @Date 2020/2/19 14:10
 * @Version 1.0
 **/
public class Sheep implements Cloneable{

    private String name;
    private String type;
    private String color;

    public Sheep(String name, String type, String color) {
        this.name = name;
        this.type = type;
        this.color = color;
    }

    @Override
    public Object clone() {
        Sheep sheep = null;
        try {
            sheep = (Sheep) super.clone();
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        return sheep;
    }

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return type;
    }

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

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

}

使用sheep调用clone()方法实现浅拷贝

/**
 * @author yly
 * @ClassName Demo
 * @Date 2020/2/19 14:14
 * @Version 1.0
 **/
public class Demo {
    public static void main(String[] args) {
        Sheep sheep = new Sheep("tom", "山羊", "白色");
        Sheep sheep1 = (Sheep) sheep.clone();//克隆
        Sheep sheep2 = (Sheep) sheep.clone();//克隆

        System.out.println(sheep.getName()+"--"+sheep.getType()+"--"+sheep.getColor());
        System.out.println(sheep1.getName()+"--"+sheep1.getType()+"--"+sheep1.getColor());
        System.out.println(sheep2.getName()+"--"+sheep2.getType()+"--"+sheep2.getColor());
    }
}

第二种: 实现Serializable ,读取二进制流

/**
 * @author yly
 * @ClassName Sheep2
 * @Date 2020/2/19 23:00
 * @Version 1.0
 **/
public class DeepCopy implements Serializable,Cloneable {

    private String name;
    private String type;
    private String color;

    public DeepCopy(String name, String type, String color) {
        this.name = name;
        this.type = type;
        this.color = color;
    }

    public String getName() {
        return name;
    }

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

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

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

实现深拷贝

/**
 * @author yly
 * @ClassName DeepProtoType
 * @Date 2020/2/19 23:03
 * @Version 1.0
 **/
public class DeepProtoType implements Serializable,Cloneable {

    public String name;

    public DeepCopy deepCopy;

    public DeepProtoType() {

    }
    //第一种 深拷贝方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object deep = null;

        deep = super.clone();

        DeepProtoType deepProtoType = (DeepProtoType)deep;
        deepProtoType.deepCopy = (DeepCopy) deepCopy.clone();
        return deepProtoType;
    }

    //深拷第二种
    public Object deepClone(){
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        try {
            //序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            //反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            DeepProtoType copyObj = (DeepProtoType)ois.readObject();
            return copyObj;
        } catch (IOException | ClassNotFoundException e) {
           return null;
        }finally {
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            }catch (Exception e){
                System.out.println(e.getMessage());
            }
        }
    }
}

创建Demo调用两种深拷贝方法

/**
 * @author yly
 * @ClassName Client
 * @Date 2020/2/19 23:14
 * @Version 1.0
 **/
public class Demo{
    public static void main(String[] args) throws CloneNotSupportedException {
        DeepProtoType deepProtoType = new DeepProtoType();
        deepProtoType.name = "deepType";
        deepProtoType.deepCopy = new DeepCopy("小花","岩羊","棕色");

        //方式1 深拷贝
        DeepProtoType deep = (DeepProtoType)deepProtoType.clone();

        System.out.println(deepProtoType.deepCopy.getName()+"---"+deepProtoType.deepCopy.hashCode());
        System.out.println(deep.deepCopy.getName()+"---"+deep.deepCopy.hashCode());

        System.out.println();
        //方式二 深拷贝
        DeepProtoType deep2 = (DeepProtoType)deepProtoType.deepClone();
        System.out.println(deepProtoType.deepCopy.getName()+"---"+deepProtoType.deepCopy.hashCode());
        System.out.println(deep2.deepCopy.getName()+"---"+deep2.deepCopy.hashCode());
    }
}

原型模式的优点:简化对象创建过程,提高效率。如果原始对象发生变化,其他克隆对象也会发生相应的变化,无需修改代码

原型模式的缺点:需要每个类实现克隆的方法,对于新创建的类不难,但是对于已经存在的类进行改造时有时会很复杂。需要修改源代码。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值