学习笔记

Android源码设计模式_3原型模式
Publish: 2018/8/15   

定义

用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

使用场景

  1. 类初始化需要消耗非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。
  2. 通过new产生一个对象需要非常繁琐的数据准备或访问权限,这时可以使用原型模式。
  3. 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。

注意: 通过实现Cloneable接口的原型模式在调用clone函数构造实例时并不一定比通过new操作速度快,只有当通过new构造对象较为耗时或者说成本较高时,通过clone方法才能够获得效率上的提升。

简单实现

WordDocument扮演的是ConcretePrototype角色,而Cloneable是代表prototype角色。Cloneable是一个标识接口,标识这个类的对象是可拷贝的。如果没有实现Cloneable接口却调用了clone()函数将抛出异常。

 public class WordDocument implements Cloneable{
     private String mText;
     private ArrayList<String> mImages=new ArrayList();

     public WordDocument(){}

     //clone是Object的方法
     @Override
     protected WordDocument clone(){
         try{
             WordDocument doc = (WordDocument) super.clone();
             doc.mText=this.mText;
             doc.mImages=this.mImages;
             return doc;
         } catch (Exception e){
         }
         return null;
     }
 }

浅拷贝和深拷贝

拷贝规则:

  1. 基本类型

    如果变量是基本很类型,则拷贝其值,比如int、float等。

  2. 对象

    如果变量是一个实例对象,则拷贝其地址引用,也就是说此时新对象与原来对象是公用该实例变量。

  3. String字符串

    若变量为String字符串,则拷贝其地址引用。但是在修改时,它会从字符串池中重新生成一个新的字符串,原有字符串对象保持不变。

浅拷贝

上述原型模式的实现实际上只是一个浅拷贝,也成为影子拷贝,这份拷贝实际上并不是将原始文档的所有字段都重新构造了一份,而是副本文档引用原始文档的字段。当修改副本时原始文档也会改变。

深拷贝

在拷贝对象时,对于引用型的字段也要采用拷贝的形式,而不是单纯引用的形式。

 public class WordDocument implements Cloneable{
     private String mText;
     private ArrayList<String> mImages=new ArrayList();

     public WordDocument(){}

     //clone是Object的方法
     @Override
     protected WordDocument clone(){
         try{
             WordDocument doc = (WordDocument) super.clone();
             doc.mText=this.mText;
             //对mImages对象也调用clone()函数,进行深拷贝
             doc.mImages=(ArrayLis)this.mImages.clone;
             return doc;
         } catch (Exception e){
         }
         return null;
     }
 }

优缺点

优点

原型模式是在内存中二进制流的拷贝,要比直接new一个对象性能好很多,特别时要求在循环体内产生大量的对象时,原型模式可以更好地体现其优点。

缺点

直接在内存中拷贝,构造函数是不会执行的,在实际开发当中应该注意这个潜在的问题。



← Android源码设计模式_4策略模式 Android源码设计模式_2单例模式 →

Powered by Hexo, Theme designs by @hpcslag.
Style-Framework Tocas-UI designs by @yamioldmel