設(shè)計(jì)模式——原型模式

簡(jiǎn)介:
  • 原型模式是一個(gè)創(chuàng)建型的模式。
  • 通過給出一個(gè)原型對(duì)象來指明所創(chuàng)建的對(duì)象的類型,然后用復(fù)制這個(gè)原型對(duì)象的辦法創(chuàng)建出更多同類型的對(duì)象。
  • 原型模式要求對(duì)象實(shí)現(xiàn)一個(gè)可以“克隆”自身的接口,這樣就可以通過復(fù)制一個(gè)實(shí)例對(duì)象本身來創(chuàng)建一個(gè)新的實(shí)例,這樣一來,通過原型實(shí)例創(chuàng)建新的對(duì)象,就不再需要關(guān)心這個(gè)實(shí)例本身的類型,只要實(shí)現(xiàn)了克隆自身的方法,就可以通過這個(gè)方法來獲取新的對(duì)象,而無須再去通過new來創(chuàng)建。
使用場(chǎng)景
  1. 原型模式多用于創(chuàng)建復(fù)雜的或者構(gòu)造耗時(shí)的實(shí)例,因?yàn)檫@種情況下,復(fù)制一個(gè)已經(jīng)存在的實(shí)例可使程序運(yùn)行更高效。
  2. 通過new產(chǎn)生的一個(gè)對(duì)象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或者權(quán)限,這時(shí)可以使用原型模式。
  3. 個(gè)對(duì)象需要提供給其他對(duì)象訪問,而且各個(gè)調(diào)用者可能都需要修改其值時(shí),可以考慮使用原型模式拷貝多個(gè)對(duì)象供調(diào)用者使用,即保護(hù)性拷貝。
原型模式的參與角色
  1. 客戶角色:客戶類提出創(chuàng)建對(duì)象的請(qǐng)求。
  2. 抽象原型角色:這是一個(gè)抽象角色,通常由一個(gè)java接口或抽象類實(shí)現(xiàn),具體原型都需要實(shí)現(xiàn)該接口。
  3. 具體原型角色:客戶端所需要的被復(fù)制的對(duì)象。
實(shí)例演示
/**
 *
 * @ Description:Cloneable 扮演抽象原型角色  Book 扮演具體原型角色,當(dāng)然也可以設(shè)成抽象原型角色,由其他具體對(duì)象來實(shí)現(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.構(gòu)建書本對(duì)象
        Book book1 = new Book();        
        // 2.編輯書本,添加圖片
        book1.setTitle("書1");
        book1.addImage("圖1");
        book1.showBook();

        // 以原型文檔為原型,拷貝一份副本
        Book book2 = (Book) book1.clone();
        book2.showBook();
        // 修改圖書副本,不會(huì)影響原始書本
        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的內(nèi)容是一樣的。而book2修改了“標(biāo)題”-字符串(基本的數(shù)據(jù)類型),并不影響book1的標(biāo)題,這就保證了book1的安全性。

淺拷貝引用
public class Client {

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

        // 以原型文檔為原型,拷貝一份副本
        Book book2 = (Book) book1.clone();
        book2.showBook();
        // 修改圖書副本,不會(huì)影響原始書本
        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----------------------
備注

最后兩個(gè)書本內(nèi)容輸出是一致的。引用類型的新對(duì)象book2的image只是單純指向了this.image引用,并沒有重新構(gòu)造一個(gè)image對(duì)象,然后將原始書本的圖片添加到新的image對(duì)象中,這樣導(dǎo)致book2中的image與原始書本中的是同一個(gè)對(duì)象。因此,修改其中一個(gè)書本的圖片,另一個(gè)書本也會(huì)受到影響。
  如何解決?因?yàn)镺bject類的clone方法只會(huì)拷貝對(duì)象中的基本的數(shù)據(jù)類型,對(duì)于數(shù)組、集合、容器對(duì)象、引用對(duì)象等都不會(huì)拷貝;所以采用深拷貝。

深拷貝應(yīng)用
/**
     * 重寫拷貝方法
     */
    @Override
    protected Book clone()  {
        try {
            Book book = (Book) super.clone();
            // 對(duì)image對(duì)象也調(diào)用clone()函數(shù),進(jìn)行拷貝
            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本身,實(shí)現(xiàn)了完全的拷貝,這樣再互不影響。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計(jì)原則時(shí)需要注意以下幾點(diǎn):a) 高內(nèi)聚、低耦合和單一職能的“沖突”實(shí)際上,這兩者...
    彥幀閱讀 3,898評(píng)論 0 14
  • 原型模式 介紹 在許多面向?qū)ο蟮膽?yīng)用程序中,有些對(duì)象的創(chuàng)建代價(jià)過大或者過于復(fù)雜。要是可以重建相同的對(duì)象并作輕微的改...
    666真666閱讀 532評(píng)論 0 2
  • 前言 Android的設(shè)計(jì)模式系列文章介紹,歡迎關(guān)注,持續(xù)更新中: Android的設(shè)計(jì)模式-設(shè)計(jì)模式的六大原則一...
    四月葡萄閱讀 5,687評(píng)論 4 10
  • 一、定義 用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并通過復(fù)制這些原型創(chuàng)建新的對(duì)象。 原型模式本質(zhì)上就是對(duì)象拷貝。使用原型模式...
    Utte閱讀 536評(píng)論 0 0
  • 發(fā)展不均衡的表現(xiàn)很多種,印象比較深刻的就是那些很有本事的供應(yīng)商脾氣都非常大,但是這并不妨礙她們出色的工作能力,有一...
    湯圓君花生醬A15003閱讀 419評(píng)論 0 0

友情鏈接更多精彩內(nèi)容