原型模式用于创建重复对象,能逃避构造方法的约束
原型模式的本质是对象克隆
对象克隆的方式
浅克隆:实现 cloneable 接口
深克隆:实现 Serializable 接口,使用二进制流读写
@SneakyThrows
private Object deepClone() {
@Cleanup ByteArrayOutputStream bos = new ByteArrayOutputStream();
@Cleanup ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
@Cleanup ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
@Cleanup ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
也可以使用 JSON 序列化来实现深克隆
原型模式有三个角色:
原型角色:定义用于克隆实例的方法,抽象类或接口
具体原型角色:继承原型角色,实现克隆方法
使用者角色:调用克隆方法,生成新实例
原型角色
public abstract class Shape implements Cloneable {
public abstract void print();
@Override
protected Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
具体原型角色
public class Circle extends Shape {
@Override
public void print() {
System.out.println("Circle");
}
}
public class Square extends Shape{
@Override
public void print() {
System.out.println("Square");
}
}
使用者角色
public class ShapeCache {
private static final Map<String, Shape> cacheMap = new HashMap<>();
static {
cacheMap.put("Circle", new Circle());
cacheMap.put("Square", new Square());
}
public static Shape getShape(String type) {
return (Shape) cacheMap.get(type).clone();
}
}
测试
public static void main(String[] args) {
Shape circle = ShapeCache.getShape("Circle");
Shape circle0 = ShapeCache.getShape("Circle");
System.out.println(circle == circle0);
}
// false
spring 中的 scope = "prototype" 是通过克隆容器中的对象模板,来快速创建实例的