#21种设计模式之--4--Prototype(原型)#

一、介绍及定义

①介绍:原型模式是一种创建型的模式。原型两个字表明了该模式应该有一个样板实例,用户从这个样板实例中复制出
一个内部属性一致的对象,这个过程通俗的讲就是“克隆”。这个被复制的实例就称为“原型”。
②定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
③场景:用于创建复杂的和耗时的实例
注:通过实现Cloneable接口的原型模式在调用clone函数构造实例时并不一定比new构建速度快,只有通过new对象成本较高或者耗时时,才会使用clone构建对象。

二、UML类图

原型模式.png

三、案例

创建

public class WordDocument implements Cloneable{

private String name;

private ArrayList<String>  mlist=new ArrayList<>();
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}


public ArrayList<String> getMlist() {
    return mlist;
}

public void addString(String text) {
    this.mlist.add(text);
}

@Override
protected WordDocument clone()  {

    try {

        WordDocument  wordDocument= (WordDocument) super.clone();
           wordDocument.name = this.name;
           wordDocument.mlist=this.mlist;

        return wordDocument;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return  null;
}

public void showDocument(){
    Log.e("TAG","==============start==============");
    Log.e("TAG","name====="+name);
    for (String string:mlist){
        Log.e("TAG","text====="+string);
    }

    Log.e("TAG","==============end=================");
}
}

使用

  WordDocument wordDocument = new WordDocument();
    wordDocument.setName("张三");
    wordDocument.addString("张三");
    wordDocument.addString("张三");
    wordDocument.addString("张三");
    wordDocument.showDocument();

    WordDocument clone = wordDocument.clone();
    clone.showDocument();



    clone.setName("李四");
    clone.showDocument();
    wordDocument.showDocument();

打印结果

Paste_Image.png

四、浅拷贝和深拷贝

上述例子其实是一个浅拷贝,也称影子拷贝,这种拷贝并不是将原始数据字段拷贝了一份,只是引用了原始数据对象字段。只是指向了一个相同的内存地址。
有下面打印

  WordDocument wordDocument = new WordDocument();
    wordDocument.setName("张三");
    wordDocument.addString("张三");
    wordDocument.addString("张三");
    wordDocument.addString("张三");
    wordDocument.showDocument();

    WordDocument clone = wordDocument.clone();
    clone.showDocument();



    clone.setName("李四");
    clone.addString("李四");
    clone.addString("李四");
    clone.addString("李四");
    clone.showDocument();
    wordDocument.showDocument();

Paste_Image.png

打印结果发现最后两次一样,修改一个另一个也变,所以这就是浅拷贝,解决可以采用深拷贝,改变一下方法如下

 @Override
  protected WordDocument clone()  {

     try {

        WordDocument  wordDocument= (WordDocument) super.clone();
             wordDocument.name = this.name.clone();
               wordDocument.mlist= (ArrayList<String>) this.mlist.clone();

        return wordDocument;
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    return  null;
}

五、源码中原型设计模式

①ArrayList中的使用

上面例子可知ArrayList也有clone()方法,如下

 @Override 
  public Object clone() {
    try {
        ArrayList<?> result = (ArrayList<?>) super.clone();
        result.array = array.clone();
        return result;
    } catch (CloneNotSupportedException e) {
       throw new AssertionError();
    }
}

其实该方法很简单先克隆本身再克隆对象中元素,为啥size没有克隆?因为size为整形,并不是一个对象,clone()为Object中方法,不是一个引用类型,是值类型,不需要克隆。

②Intent中的使用

   Intent intent = new Intent();
    intent.clone();

查看源码

   @Override
   public Object clone() {
    return new Intent(this);
  }
  private Intent(Intent o, boolean all) {
    this.mAction = o.mAction;
    this.mData = o.mData;
    this.mType = o.mType;
    this.mPackage = o.mPackage;
    this.mComponent = o.mComponent;
    if (o.mCategories != null) {
        this.mCategories = new ArraySet<String>(o.mCategories);
     }
    }

小礼物走一走,来

猜你喜欢

转载自blog.csdn.net/duanpengde123/article/details/89814314
今日推荐