一.介绍
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。当直接创建对象的代价比较大时,则采用这种模式
二.UML类图
三.浅克隆与深克隆
学习原型模式之前,先要了解一下浅克隆与深克隆
-
浅克隆:对于非基本属性类型(图中的Product),仍指向原有属性所指向的内存地址,如果原型对象修改了Product的productName属性,那么克隆对象会受到影响,反之亦然
-
深克隆:对于非基本属性类型(图中的Product),不再指向原有属性所指向的内存地址,原型对象与克隆对象不会相互影响
四.浅拷贝的实现方式
java提供的克隆机制(实现Cloneable接口,重写clone方法)
public class Prototype implements Cloneable {
private Product product;
public Prototype(Product product) {
this.product = product;
}
public Product getProduct() {
return product;
}
@Override
protected Prototype clone() throws CloneNotSupportedException {
return (Prototype) super.clone();
}
}
class Product{
private String productName;
public Product(String productName) {
this.productName = productName;
}
}
验证浅克隆
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
//原型对象
Prototype prototype = new Prototype(new Product("A"));
//克隆对象
Prototype clone = prototype.clone();
//原型对象与克隆对象的product属性指向同一块内存空间
System.out.println(prototype.getProduct() == clone.getProduct()); //true
}
}
五.深拷贝的实现方式
- java提供的克隆机制
public class Prototype implements Cloneable {
private Product product;
public Prototype(Product product) {
this.product = product;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
@Override
protected Prototype clone() throws CloneNotSupportedException {
Prototype clone = (Prototype) super.clone();
//将对象的引用替换为拷贝的引用
clone.setProduct(product.clone());
return clone;
}
}
//赋予引用对象拷贝的能力
class Product implements Cloneable{
private String productName;
public Product(String productName) {
this.productName = productName;
}
@Override
protected Product clone() throws CloneNotSupportedException {
return (Product) super.clone();
}
}
- java提供的序列化机制
@Override
protected Prototype clone() throws CloneNotSupportedException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//将对象写入流
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(this);
} catch (IOException e) {
e.printStackTrace();
}
//将对象从流中读取出来
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
return (Prototype) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
六.在Spring中的应用
org.springframework.beans.factory.support.AbstractBeanDefinition