原型模式

关于克隆,我们会想到《西游记》里面孙悟空的猴毛分身,也会想到《火影忍者》里面的影分身之术。他们都是用一个物体复制若干个一模一样的物体。在面向对象的系统中,我们也可以通过克隆来复制一些对象---也就是我们所说的原型模式

用原型实例指定创建对象的种类,通过拷贝这些原型创建新的对象,也就是利用一个原型对象来指明我们要创建对象的类型,然后通过复制这个对象来获取一模一样的对象实例

一个简单的原型模式Demo

public class PrototypeClass implements Cloneable{
    @Override
    protected PrototypeClass clone(){
        PrototypeClass prototypeClass = null;
        try {
            prototypeClass = (PrototypeClass)super.clone();
        }catch (CloneNotSupportedException e){

        }
        return prototypeClass;
    }
}
  • 实现Cloneable接口,在JVM中只有具有这个标记的对象才有可能被拷贝
  • 重写覆盖Clone()方法

为什么要用原型模式

  • 性能优良。 原型模式是在内存二进制流的拷贝,比直接new一个对象性能要好得多。所以特别是要在一个循环体内产生大量对象的时候,原型模式更好体现其优点
  • 避开构造函数的束缚(既是优点也是缺点)
    直接在内存中拷贝,构造函数是不会执行的

原型模式应用场景

  1. 资源优化场景
  2. 性能和安全要求场景
  3. 一个对象多个修改者的场景

两种拷贝方式

浅拷贝

只拷贝本对象,对象内部的数组、引用对象都不拷贝,还是指向原生对象的内部元素地址。原始类型(int、long、char)以及String都会被拷贝

如何才能保证成员变量不被拷贝(保证以下两个条件)
  • 必须是类的成员变量,而不是方法内变量
  • 必须是一个可变的引用对象,而不是一个原始类型或者不可变对象
public class Thing implements Cloneable {
    private List<String> list = new ArrayList<String>();

    @Override
    protected Thing clone(){
        Thing thing = null;
        try {
            thing = (Thing)super.clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return thing;
    }
    
    public void setValue(String value){
        this.list.add(value);
    }
    
    public List<String> getValue(){
        return this.list;
    }
}

浅克隆是不安全的方式,两个对象共享了一个私有变量,大家都能够进行修改。

深拷贝

public class DeepThing implements Cloneable {
    private ArrayList<String> list = new ArrayList<String>();

    @Override
    protected DeepThing clone(){
        DeepThing thing = null;
        try {
            thing = (DeepThing)super.clone();
            this.list = (ArrayList<String>)this.list.clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return thing;
    }

    public void setValue(String value){
        this.list.add(value);
    }

    public List<String> getValue(){
        return this.list;
    }
}

总结

  • 原型模式向客户隐藏了创建对象的复杂性,客户只需要知道创建对象类型,就可以获得对象一模一样的新对象。
  • 有两种克隆方式:深克隆、浅克隆
    • 浅克隆;不安全,对象公有私有变量
    • 有时对象的复制可能会比较复杂
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容