原型模式是指用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道创建的细节
工作原理是通过一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝他们自己来实施创建
假如现有有一个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就会使用原型模式来创建