原型设计模式

一、介绍及定义

①介绍:原型模式是一种创建型的模式。原型两个字表明了该模式应该有一个样板实例,用户从这个样板实例中复制出
一个内部属性一致的对象,这个过程通俗的讲就是“克隆”。这个被复制的实例就称为“原型”。
②定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
③场景:用于创建复杂的和耗时的实例
注:通过实现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);
     }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容