原型模式是指用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道创建的细节
工作原理是通过一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝他们自己来实施创建
假如现有有一个Cat对象,需要拷贝很多个。如果使用源对象的get方法来赋值给新对象属性值,就会很麻烦,而且如果新增一个属性,也要依次修改。
所以需要使用原型模式中的浅拷贝,即实现Cloneable接口,调用clone方法
浅拷贝的介绍:
对于数据类型是基本数据类型的成员变量,直接进行值传递
对于数据类型是引用类型的成员变量,进行引用传递
浅拷贝使用默认的clone方法实现
public class Cat implements Cloneable{
private String name;
private Integer age;
private String color;
public Cat(String name, Integer age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
进行克隆
public static void main(String[] args) throws CloneNotSupportedException {
Cat cat = new Cat("tomcat", 1, "橘色");
Cat cat1 = (Cat)cat.clone();
Cat cat2 = (Cat)cat.clone();
Cat cat3 = (Cat)cat.clone();
Cat cat4 = (Cat)cat.clone();
System.out.println(cat);
System.out.println(cat1);
System.out.println(cat2);
System.out.println(cat3);
System.out.println(cat4);
}
输出结果
如果我们想实现深拷贝,深拷贝的基本介绍:
复制对象的所有基本数据类型的成员变量值
为所有引用数据类型的成员变量申请存储空间,并复制每个引用类型成员变量所引用的对象,直到该对象所达的所有对象,即对整个对象进行拷贝
实现方式1:重写clone方法实现
实现方式2:通过对象序列化实现
public class Cat implements Cloneable, Serializable {
private String name;
private Integer age;
private String color;
private Cat mom;
//方式1
@Override
protected Object clone() throws CloneNotSupportedException {
Cat cat = (Cat)super.clone();
cat.mom = (Cat)mom.clone();
return cat;
}
//方式2
public Object clone2(){
//创建流对象
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
Cat cat = null;
try {
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this); //把当前对象以对象流的方式输出
//反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
cat = (Cat)ois.readObject();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
bos.close();
bis.close();
oos.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return cat;
}
}
spring在创建bean的时候默认是单例的,而如果我们在bean标签中把scope属性设置为prototype,spring就会使用原型模式来创建