二十三种设计模式之自我了解---原型模式(Prototype)

原型模式

        原型模式属于三大类中的创建模式(处理对象创建的设计模,试图根据实际情况使用合适的方式创建对象):俗语称之为简单高效的“Copy”,这里的copy不是,copy一句话,而是一个实例,在copy之前要有一个对象,这个对象叫做“原型

主要运用方法

  • 实现类Cloneable,这个类里有一个接口Cloneable,重写方法clone(),实现克隆自己的操作。
  • 通过序列化,实现Serializable接口
  • 构造方法

原型模式可分为浅拷贝和深拷贝,众所周知,代码存储又地址和值一直组成

浅拷贝:只复制源对象的地址,当源对象的属性值改变时,拷贝对象也随之改变,name变化,因为他们同一指向一块内存地址

深拷贝:拷贝所有的属性,也会随之动态分配内存,不属于同一内存地址,拷贝前后两个对象互不影响

代码探究

想到拷贝对象,应该都会一下操作:

(1)建立一个实体,也叫定义一个类,将定义需要拷贝对想的属性

public class prototype {
    private Integer id;
    private String name;

    public prototype(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "prototype{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

(2)若要拷贝这个对象,最简单粗暴的也就是实例化在工厂实例化,需要拷贝多少,就直接实例化多少,在实例化之前,需要定义模式,就是这个人的五官。作为对比,用hash值作为观察

public class Factory {
    public static void main(String[] args) {
        
        Prototype p=new Prototype(1,"xiaoxiao");
        //实例化
        Prototype cloneA = new Prototype(p.getId(), p.getName());
        Prototype cloneB = new Prototype(p.getId(), p.getName());
        System.out.println(cloneA.hashCode()+"对应"+cloneA);
        System.out.println(cloneB.hashCode()+"对应"+cloneB);
    }
}

 

这个方法有一个明显的问题,代码复用率太高,并且,如果是大量的需要克隆,那是不是代码量极高,然后就有了浅拷贝,深拷贝

浅拷贝

实现Cloneable,重写clone方法

public class PrototypeA implements Cloneable{
    private Integer id;
    private String name;

    public PrototypeA(Integer id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "prototype{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

在工厂中只要调用clone方法就可以直接执行拷贝操作,不用去赋值属性

public class Factory {
    public static void main(String[] args) throws CloneNotSupportedException {

        PrototypeA pA=new PrototypeA(1,"longlong");
        PrototypeA cloneA = (PrototypeA) pA.clone();
        PrototypeA cloneB =(PrototypeA) pA.clone();
        System.out.println(cloneA.hashCode()+"对应"+cloneA);
        System.out.println(cloneB.hashCode()+"对应"+cloneB);
    }
}

解决了属性问题,如果我要添加其他模型了,是不是我还得建造一个实体,还得在主函数继续上一个同样的操作了

 

,不出意外,会得到一个hashcode相同的对象,说明什么了,羊毛出在同一个羊上,但是我现在是对另一个实体进行克隆,这算什么回事,生生把两个不同的东西结合成同个一个了。那怎么解决了?

办法一:在重写clone()方法,在另外一个实体中。

办法二,使用序列化

重点说序列化

序列化
 * 将一个特定的数据结构转换为一组字节的过程称之为序列化 --->>> 特定 数据结构 转换为 字节流
反序列化
* 将一组字节转换为特定的数据结构的过程称之为反序列化----->>>一组字节流 转换为特定 的数据结构

这里为什么使用了!复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。。。。。。。。。。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值