一 定义
原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
调用者不需要知道任何创建细节,不调用构造函数
属于创建型模式
二 使用场景
1. 类初始化消耗资源过多
2. new产生的一个对象需要非常繁琐的过程(数据准备,访问权限等)
3. 构造函数比较复杂
4. 循环体中生产大量对象时
三 实现
(一)通常可以通过反射的方式来进行复制对象的操作
public class BeanUntils { public static Object copy(Object prototype){ Class clazz = prototype.getClass(); Object returnValue = null; try { returnValue = clazz.newInstance(); for (Field field : clazz.getDeclaredFields()){ field.setAccessible(true); field.set(returnValue,field.get(prototype)); } }catch (Exception e){ e.printStackTrace(); } return returnValue; } }
(二)浅克隆 implements cloneable
对象有list属性,对克隆之后的对象更改list的值,原对象的也会被修改
@Data public class Prototype implements Cloneable{ private String name; private Integer age; private List<String> hobbies; @Override protected Prototype clone() throws CloneNotSupportedException { return (Prototype)super.clone(); } @Override public String toString() { return "Prototype{" + "name='" + name + '\'' + ", age=" + age + ", hobbies=" + hobbies + '}'; } }
public class Test {
public static void main(String[] args) throws Exception{
Prototype p = new Prototype();
p.setAge(10);
p.setName("ddd");
List<String> list = new ArrayList<>();
list.add("fff");
p.setHobbies(list);
Prototype p2 = p.clone();
p2.getHobbies().add("222");
System.out.println(p);
System.out.println(p2);
System.out.println(p == p2);
System.out.println(p.getHobbies() == p2.getHobbies());
}
}
结果:
Prototype{name='ddd', age=10, hobbies=[fff, 222]}
Prototype{name='ddd', age=10, hobbies=[fff, 222]}
false
true
(三)深克隆
public Prototype deepClone() throws Exception{ ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return (Prototype)ois.readObject(); }
注意需要 implements Serializable
四 优缺点
优点:性能优良,Java自带的原型模式是基于内存二进制流的拷贝,比直接new一个对象性能上提升了许多。
可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,简化了创建过程
缺点:必须配备克隆(或者可拷贝)的方法
当对已有类进行改造的时候,需要需代码,违反了开笔原则
深克隆,浅克隆需要运用得当