23种设计模式-原型模式


欢迎访问我的个人博客(点击进入)

原型模式

1.实际案例

克隆出10只相同的羊,要求属性完全相同

2.传统方式解决

public class Client {
    public static void main(String[] args) {
        Sheep sheep = new Sheep("tom",1,"白色");
        Sheep sheep1 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
        Sheep sheep2 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
        Sheep sheep3 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
        Sheep sheep4 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
        Sheep sheep5 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
        Sheep sheep6 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());

        System.out.println(sheep);
        System.out.println(sheep1);
        System.out.println(sheep2);
        System.out.println(sheep3);
        System.out.println(sheep4);
        System.out.println(sheep5);
        System.out.println(sheep6);
    }
}

方式弊端:

  1. 在创建新的对象时,总是需要重新获取原始对象的属性,如果创建的对象比较复杂时,效率较低
  2. 总是要初始化对象,儿额不是动态的获得对象运行时的状态,不够灵活
    改进的思路:

Java中Object是所有类的基类,提供了一个clone()方法,可以将java对象复制一份,但是需要实现Cloneable接口=》原型模式

3.原型模式的概念

  • 用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象
  • 原型模式是一种创建型的设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的细节
  • 通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝他们字节来实施创建,即对象,clone()

4.原型模式实现(浅拷贝)

需要克隆的类实现Coneable接口,重写clone()方法,完成克隆,程序会拥有更高的扩展性

public class Sheep implements Cloneable {
    private String name;
    private int age;
    private String color;
     /**
     * 克隆该实例,使用默认的克隆方法来完成
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Sheep sheep = null;
        try {
            sheep = (Sheep) super.clone();
        }catch (Exception e){
            System.out.println(e.getMessage());
        }

        return sheep;
    }
}

这种方式是浅拷贝,当数据中有对象时,拷贝出的对象只是原对象指向的空间,没有创建出新的对象

5.原型模式(深拷贝)

存在的问题:

  • 当对象中的成员变量是引用类型的,如一个类对象,当出现这样的情况时,进行浅拷贝就会出现,只能拿到该对想的存储地址的问题

所以我们需要进行深拷贝:

5.1 clone方法

/**
 * 深拷贝
 * 方式1:重写clone方法
 */
@Override
protected Object clone() throws CloneNotSupportedException {
    Object deep = null;
    //完成对基本数据类型的克隆
    deep = super.clone();
    //对引用类型的属性,进行单独处理
    DeepProtoType deepProtoType = (DeepProtoType) deep;
    deepProtoType.deepCloneableTarget = (DeepCloneableTarget) deepCloneableTarget.clone();
    return deep;
}

5.2 反序列化

/**
     * 深拷贝
     * 方式二:序列化反序列化
     * @return
     */
    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 deep = (DeepProtoType) ois.readObject();
            return deep;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }finally {
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值