HyZxx

导航

 

一 定义

  原型模式(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一个对象性能上提升了许多。

    可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,简化了创建过程

缺点:必须配备克隆(或者可拷贝)的方法

  当对已有类进行改造的时候,需要需代码,违反了开笔原则

  深克隆,浅克隆需要运用得当

 

posted on 2020-03-07 16:11  HyZxx  阅读(184)  评论(0编辑  收藏  举报