設(shè)計模式-原型模式

原型模式也屬于創(chuàng)造型設(shè)計模式玄柠,他是通過復(fù)制一個已經(jīng)存在的對象實例而得到一個新的實例,避免繁瑣的實例化過程霎苗。在這里被復(fù)制的對象實例叫做原型争剿,復(fù)制原型也叫克隆對象已艰,有深克隆和淺克隆兩種。

淺克隆

對值類型的成員變量進(jìn)行值的復(fù)制,對引用類型的成員變量只復(fù)制引用,不復(fù)制引用的對象蚕苇;也就是值類型和引用進(jìn)行復(fù)制

深克隆

在淺克隆的基礎(chǔ)上哩掺,對引用類型也進(jìn)行克隆,而不僅僅是引用

原型克隆的 UML 類圖如下:


client:提出創(chuàng)建對象請求涩笤;
propotype:抽象原型嚼吞,給出所有具體原型需要實現(xiàn)的接口;
concretePropotype:具體的原型對象蹬碧,需要被復(fù)制的對象舱禽;

仍然加以代碼實現(xiàn)
先來淺拷貝,抽象原型

public interface Prototype  extends Cloneable {
 public Object clone() ;
}

//具體克隆對象
public class ConcretePropotype implements Propotype {

    private String name;
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

客戶端測試下

public class Client {

    public static void main(String[] args) {
        ConcretePropotype propotype=new ConcretePropotype();
        propotype.setName("zhangsan");
        propotype.setAge(11);
        
        ConcretePropotype propotypeClone=(ConcretePropotype) propotype.clone();
        System.out.println(propotypeClone.getName());
        
        propotypeClone.setName("lisi");
        propotypeClone.setAge(12);
        
        System.out.println(propotype.getAge());
        System.out.println(propotypeClone.getName());
    }

}

這個屬于淺克隆,沒有涉及到引用類型恩沽,為了驗證下誊稚,繼續(xù)引入一個對象Student

public class Student {

    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

這里具體原型對象增加引入,代碼為:

public class ConcretePropotype2 implements Propotype {

    private String name;
    private int age;
    private Student student;

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

進(jìn)入 Client 端進(jìn)行驗證一下

public class Client2 {

    public static void main(String[] args) {
        ConcretePropotype2 propotype=new ConcretePropotype2();
        Student stu=new Student();
        stu.setAge(50);
        stu.setName("東郭");
        propotype.setStudent(stu);
        
        ConcretePropotype2 propotypeClone=(ConcretePropotype2) propotype.clone();
        propotypeClone.getStudent().setName("西施");
        propotypeClone.getStudent().setAge(100);
        
        System.out.println("原型:"+propotype.getStudent().getName());
        System.out.println("克隆后:"+propotypeClone. getStudent().getName());
        
        System.out.println("原型:"+propotype.getStudent().getAge());
        System.out.println("克隆后:"+propotypeClone. getStudent().getAge());
    }

}

由于是淺克隆飒筑,只是引用復(fù)制了片吊,所以克隆后把原來的對象也修改了绽昏,最后的結(jié)果是

原型:西施
克隆后:西施
原型:100
克隆后:100

這個情況就會出現(xiàn)很大問題协屡,把原來的對象徹底修改了,這可是不想遇到的全谤,此時肤晓,深克隆粉墨登場,來解決這個問題认然;但是為了深克隆补憾,需要克隆的對象可序列化,之前的Student對象需要實現(xiàn)public class Student implements Serializable卷员,這樣在 clone 對象里面利用串行化來做深復(fù)制盈匾。

public Object deepClone(){
  try {
   ByteArrayOutputStream bo = new ByteArrayOutputStream();
   ObjectOutputStream oo = new ObjectOutputStream(bo);   
   oo.writeObject(this);   
   //將對象從流里面讀出來
   ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
   ObjectInputStream oi = new ObjectInputStream(bi);
   return oi.readObject(); 
  } catch (IOException | ClassNotFoundException e) {
   e.printStackTrace();
   return null;
  }
 }

當(dāng)然還可以逐個對象的引用進(jìn)行復(fù)制,那樣引用層次較淺還可以接受毕骡,太深的話操作性非常不好削饵。還是建議利用串行化來做深復(fù)制岩瘦。

深度克隆之后完全就是兩個對象了,互相不干擾窿撬,但需要克隆的對象序列化启昧。既然是從克隆出來的,所以依附就小多了劈伴,只要產(chǎn)品具有克隆方法就可以克隆一個新的自己出來密末,再加以演化,就可以很方便的造出不同級別的產(chǎn)品出來跛璧。唯一的難點就是何時何地增加克隆方法严里,以及不能克隆的屬性加以transient標(biāo)識。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末追城,一起剝皮案震驚了整個濱河市田炭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌漓柑,老刑警劉巖教硫,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辆布,居然都是意外死亡瞬矩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門锋玲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來景用,“玉大人,你說我怎么就攤上這事惭蹂∩〔澹” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵盾碗,是天一觀的道長媚污。 經(jīng)常有香客問我,道長廷雅,這世上最難降的妖魔是什么耗美? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮航缀,結(jié)果婚禮上商架,老公的妹妹穿的比我還像新娘。我一直安慰自己芥玉,他們只是感情好蛇摸,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著灿巧,像睡著了一般赶袄。 火紅的嫁衣襯著肌膚如雪诬烹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天弃鸦,我揣著相機(jī)與錄音绞吁,去河邊找鬼。 笑死唬格,一個胖子當(dāng)著我的面吹牛家破,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播购岗,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼汰聋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了喊积?” 一聲冷哼從身側(cè)響起烹困,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乾吻,沒想到半個月后髓梅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡绎签,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年枯饿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诡必。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡奢方,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出爸舒,到底是詐尸還是另有隱情蟋字,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布扭勉,位于F島的核電站鹊奖,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏剖效。R本人自食惡果不足惜嫉入,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一焰盗、第九天 我趴在偏房一處隱蔽的房頂上張望璧尸。 院中可真熱鬧,春花似錦熬拒、人聲如沸爷光。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛀序。三九已至欢瞪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間徐裸,已是汗流浹背遣鼓。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留重贺,地道東北人骑祟。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像气笙,于是被迫代替她去往敵國和親次企。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 本文的主要內(nèi)容如下: 介紹原型模式 示例Java語言的clone淺克隆與深克隆實現(xiàn)深克隆 原型模式的典型應(yīng)用...
    小旋鋒的簡書閱讀 1,950評論 0 2
  • 定義 原型模式屬于對象的創(chuàng)建模式潜圃。通過給出一個原型對象來指明所有創(chuàng)建的對象的類型缸棵,然后用復(fù)制這個原型對象的辦法創(chuàng)建...
    步積閱讀 1,349評論 0 2
  • 目錄 本文的結(jié)構(gòu)如下: 引言 什么是原型模式 淺克隆和深克隆 clone() 模式的結(jié)構(gòu) 典型代碼 代碼示例 優(yōu)點...
    w1992wishes閱讀 537評論 0 0
  • 原型模式 介紹 在許多面向?qū)ο蟮膽?yīng)用程序中,有些對象的創(chuàng)建代價過大或者過于復(fù)雜谭期。要是可以重建相同的對象并作輕微的改...
    666真666閱讀 450評論 0 2
  • 一堵第、問題的提出在應(yīng)用程序中,有些對象比較復(fù)雜隧出,其創(chuàng)建過程過于復(fù)雜型诚,而且我們又需要頻繁的利用該對象,如果這個時候我們...
    Qi0907閱讀 446評論 0 0