設計模式——原型模式

簡介:
  • 原型模式是一個創(chuàng)建型的模式感昼。
  • 通過給出一個原型對象來指明所創(chuàng)建的對象的類型澈缺,然后用復制這個原型對象的辦法創(chuàng)建出更多同類型的對象娶聘。
  • 原型模式要求對象實現(xiàn)一個可以“克隆”自身的接口煮剧,這樣就可以通過復制一個實例對象本身來創(chuàng)建一個新的實例斥滤,這樣一來,通過原型實例創(chuàng)建新的對象勉盅,就不再需要關心這個實例本身的類型佑颇,只要實現(xiàn)了克隆自身的方法,就可以通過這個方法來獲取新的對象草娜,而無須再去通過new來創(chuàng)建挑胸。
使用場景
  1. 原型模式多用于創(chuàng)建復雜的或者構造耗時的實例,因為這種情況下宰闰,復制一個已經存在的實例可使程序運行更高效茬贵。
  2. 通過new產生的一個對象需要非常繁瑣的數(shù)據準備或者權限,這時可以使用原型模式移袍。
  3. 個對象需要提供給其他對象訪問解藻,而且各個調用者可能都需要修改其值時,可以考慮使用原型模式拷貝多個對象供調用者使用葡盗,即保護性拷貝螟左。
原型模式的參與角色
  1. 客戶角色:客戶類提出創(chuàng)建對象的請求。
  2. 抽象原型角色:這是一個抽象角色觅够,通常由一個java接口或抽象類實現(xiàn)胶背,具體原型都需要實現(xiàn)該接口。
  3. 具體原型角色:客戶端所需要的被復制的對象喘先。
實例演示
/**
 *
 * @ Description:Cloneable 扮演抽象原型角色  Book 扮演具體原型角色钳吟,當然也可以設成抽象原型角色,由其他具體對象來實現(xiàn)
 * @Version: $version$
 */
public class Book implements  Cloneable {

    private   String title;

    private ArrayList<String> images = new ArrayList<String>();


    @Override
    protected Object clone() throws CloneNotSupportedException {
       Book book = (Book) super.clone();
       return  book;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public ArrayList<String> getImages() {
        return images;
    }

    public void setImages(String images) {
        this.images.add(images);
    }
    public void showBook() {
        System.out.println("----------------------Start----------------------");

        System.out.println("title:" + title);
        for (String img : images) {
            System.out.println("image name:" + img);
        }

        System.out.println("----------------------End----------------------");
    }
}
客戶角色
public class Client {

    public static void main(String[] args) {
        // 1.構建書本對象
        Book book1 = new Book();        
        // 2.編輯書本窘拯,添加圖片
        book1.setTitle("書1");
        book1.addImage("圖1");
        book1.showBook();

        // 以原型文檔為原型红且,拷貝一份副本
        Book book2 = (Book) book1.clone();
        book2.showBook();
        // 修改圖書副本坝茎,不會影響原始書本
        book2.setTitle("書2");
        book2.showBook();

        // 再次打印原始書本
        book1.showBook();
    }
}

輸出
----------------------Start----------------------
title:書1
image name:圖1
----------------------End----------------------
----------------------Start----------------------
title:書1
image name:圖1
----------------------End----------------------
----------------------Start----------------------
title:書2
image name:圖1
----------------------End----------------------
----------------------Start----------------------
title:書1
image name:圖1
----------------------End----------------------
備注:

book2是book的一份拷貝,它和book1的內容是一樣的直焙。而book2修改了“標題”-字符串(基本的數(shù)據類型)景东,并不影響book1的標題,這就保證了book1的安全性奔誓。

淺拷貝引用
public class Client {

    public static void main(String[] args) {
        // 1.構建書本對象
        Book book1 = new Book();        
        // 2.編輯書本,添加圖片
        book1.setTitle("書1");
        book1.addImage("圖1");
        book1.showBook();

        // 以原型文檔為原型搔涝,拷貝一份副本
        Book book2 = (Book) book1.clone();
        book2.showBook();
        // 修改圖書副本厨喂,不會影響原始書本
        book2.setTitle("書2");
        book2.addImage("圖2");
        book2.showBook();

        // 再次打印原始書本
        book1.showBook();
    }
}
輸出
----------------------Start----------------------
title:書1
image name:圖1
----------------------End----------------------
----------------------Start----------------------
title:書1
image name:圖1
----------------------End----------------------
----------------------Start----------------------
title:書2
image name:圖1
image name:圖2
----------------------End----------------------
----------------------Start----------------------
title:書1
image name:圖1
image name:圖2
----------------------End----------------------
備注

最后兩個書本內容輸出是一致的。引用類型的新對象book2的image只是單純指向了this.image引用庄呈,并沒有重新構造一個image對象蜕煌,然后將原始書本的圖片添加到新的image對象中,這樣導致book2中的image與原始書本中的是同一個對象诬留。因此斜纪,修改其中一個書本的圖片,另一個書本也會受到影響文兑。
  如何解決盒刚?因為Object類的clone方法只會拷貝對象中的基本的數(shù)據類型,對于數(shù)組绿贞、集合因块、容器對象、引用對象等都不會拷貝籍铁;所以采用深拷貝涡上。

深拷貝應用
/**
     * 重寫拷貝方法
     */
    @Override
    protected Book clone()  {
        try {
            Book book = (Book) super.clone();
            // 對image對象也調用clone()函數(shù),進行拷貝
            book.image = (ArrayList<String>) this.image.clone();
            return book;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
輸出
----------------------Start----------------------
title:書1
image name:圖1
----------------------End----------------------
----------------------Start----------------------
title:書1
image name:圖1
----------------------End----------------------
----------------------Start----------------------
title:書2
image name:圖1
image name:圖2
----------------------End----------------------
----------------------Start----------------------
title:書1
image name:圖1
----------------------End----------------------
備注

將book.image指向this.image的一份拷貝拒名,而不是this.image本身吩愧,實現(xiàn)了完全的拷貝,這樣再互不影響增显。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末雁佳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子甸怕,更是在濱河造成了極大的恐慌甘穿,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梢杭,死亡現(xiàn)場離奇詭異温兼,居然都是意外死亡,警方通過查閱死者的電腦和手機武契,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門募判,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荡含,“玉大人,你說我怎么就攤上這事届垫∈鸵海” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵装处,是天一觀的道長误债。 經常有香客問我,道長妄迁,這世上最難降的妖魔是什么寝蹈? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮登淘,結果婚禮上箫老,老公的妹妹穿的比我還像新娘。我一直安慰自己黔州,他們只是感情好耍鬓,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著流妻,像睡著了一般牲蜀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上合冀,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天各薇,我揣著相機與錄音,去河邊找鬼君躺。 笑死峭判,一個胖子當著我的面吹牛,可吹牛的內容都是我干的棕叫。 我是一名探鬼主播林螃,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼俺泣!你這毒婦竟也來了疗认?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤伏钠,失蹤者是張志新(化名)和其女友劉穎横漏,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熟掂,經...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡缎浇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赴肚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片素跺。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡二蓝,死狀恐怖,靈堂內的尸體忽然破棺而出指厌,到底是詐尸還是另有隱情刊愚,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布踩验,位于F島的核電站鸥诽,受9級特大地震影響,放射性物質發(fā)生泄漏箕憾。R本人自食惡果不足惜衙传,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望厕九。 院中可真熱鬧,春花似錦地回、人聲如沸扁远。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽畅买。三九已至,卻和暖如春细睡,著一層夾襖步出監(jiān)牢的瞬間谷羞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工溜徙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留湃缎,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓蠢壹,卻偏偏與公主長得像嗓违,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子图贸,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內容

  • 設計模式概述 在學習面向對象七大設計原則時需要注意以下幾點:a) 高內聚蹂季、低耦合和單一職能的“沖突”實際上,這兩者...
    彥幀閱讀 3,741評論 0 14
  • 原型模式 介紹 在許多面向對象的應用程序中疏日,有些對象的創(chuàng)建代價過大或者過于復雜偿洁。要是可以重建相同的對象并作輕微的改...
    666真666閱讀 449評論 0 2
  • 前言 Android的設計模式系列文章介紹,歡迎關注沟优,持續(xù)更新中: Android的設計模式-設計模式的六大原則一...
    四月葡萄閱讀 5,566評論 4 10
  • 一涕滋、定義 用原型實例指定創(chuàng)建對象的種類,并通過復制這些原型創(chuàng)建新的對象净神。 原型模式本質上就是對象拷貝何吝。使用原型模式...
    Utte閱讀 468評論 0 0
  • 發(fā)展不均衡的表現(xiàn)很多種溉委,印象比較深刻的就是那些很有本事的供應商脾氣都非常大,但是這并不妨礙她們出色的工作能力爱榕,有一...
    湯圓君花生醬A15003閱讀 350評論 0 0