原型模式
原型模式属于三大类中的创建模式(处理对象创建的设计模,试图根据实际情况使用合适的方式创建对象):俗语称之为简单高效的“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()方法,在另外一个实体中。
办法二,使用序列化
重点说序列化
序列化 * 将一个特定的数据结构转换为一组字节的过程称之为序列化 --->>> 特定 数据结构 转换为 字节流反序列化 * 将一组字节转换为特定的数据结构的过程称之为反序列化----->>>一组字节流 转换为特定 的数据结构这里为什么使用了!复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。。。。。。。。。。