java設(shè)計(jì)模式Ctrl?C和Ctrl?V的原型模式詳解
記個(gè)筆記
早會(huì),你拿著電腦在會(huì)議室里新建了一個(gè)記事本,用著搜狗輸入法,瘋狂的記錄著你們部門老大的各種會(huì)議紀(jì)要。
時(shí)間很快,等散會(huì)的時(shí)候已經(jīng)中午了,此時(shí)阿良才著急忙慌的趕到。看著他手足無措的樣子,你淡定的對(duì)他說,不要急,會(huì)議內(nèi)容都被你記錄下來了,等會(huì)拷貝給他一份就好了。聽完你的話,他忐忑的心才慢慢放下。
我們?nèi)粘I钍褂秒娔X時(shí),經(jīng)常會(huì)用到的一個(gè)操作,就是復(fù)制粘貼,即 Ctrl+C和Ctrl+V。但是編程中,我們創(chuàng)建了一個(gè)對(duì)象,想在使用時(shí)拷貝出來一份該怎么辦呢。這就是今天想提到的設(shè)計(jì)模式,原型模式。
原型模式定義
以目標(biāo)對(duì)象為原型實(shí)例,通過復(fù)制的方式創(chuàng)建新對(duì)象。
其實(shí)換成人話就是:在內(nèi)存里復(fù)制一個(gè)內(nèi)容一模一樣的新的對(duì)象。
使用的時(shí)機(jī):
創(chuàng)建對(duì)象時(shí),在構(gòu)造函數(shù)中會(huì)進(jìn)行大量的資源消耗操作。舉幾個(gè)比較夸張的例子:比如說可能進(jìn)行網(wǎng)絡(luò)申請(qǐng)或者說拷貝個(gè)幾百m的數(shù)據(jù)到本地,再或者說要檢查下本地內(nèi)存卡或者電腦硬盤上有多少個(gè)文件夾。這些都是很耗時(shí)的計(jì)算,但是這些都是在創(chuàng)建該對(duì)象之前的準(zhǔn)備工作(舉例而已,可能有點(diǎn)夸張)。此時(shí)可以使用原型模式,直接在內(nèi)存中復(fù)制一個(gè)一模一樣的對(duì)象。
拷貝的區(qū)別
官方抽象的描述
- 淺拷貝:基本數(shù)據(jù)類型互不干擾,兩個(gè)引用數(shù)據(jù)類型引用,指向內(nèi)存中同一個(gè)對(duì)象。
- 深拷貝:在內(nèi)存中生成一個(gè)內(nèi)容一模一樣的引用數(shù)據(jù)對(duì)象。原型對(duì)象和生成對(duì)象互不干擾。
好理解的人話
- 淺拷貝:你在我的電腦中,創(chuàng)建了一個(gè)C盤的快捷方式??旖莘绞胶臀业碾娔X中的C盤都能打開C盤文件夾。
- 深拷貝:你把你的會(huì)議時(shí)創(chuàng)建的記錄會(huì)議的記事本,拷貝了一份給你的好友阿良。這兩個(gè)記事本中的數(shù)據(jù)互不干擾。
使用的步驟:
1. 繼承實(shí)現(xiàn)Clone接口
2. 對(duì)象內(nèi)部的基本數(shù)據(jù)類型變量,會(huì)直接拷貝。
3. 引用數(shù)據(jù)類型,可以根據(jù)需求。自行實(shí)現(xiàn)深拷貝或者淺拷貝(默認(rèn)即淺拷貝,類比成快捷方式)
實(shí)現(xiàn)代碼
/** * @author:TianLong * @date:2022/10/18 19:47 * @detail:原型模式 具體實(shí)現(xiàn)類 */ class Book implements Cloneable{ public ArrayList<String> articles = new ArrayList<>(); public String author = ""; public int price = 0; public String publishers = ""; public Book(ArrayList<String> articles, String author, int price, String publishers) { this.articles = articles; this.author = author; this.price = price; this.publishers = publishers; } @Override public Book clone() { Book book = null; try { book = (Book) super.clone(); // 引用數(shù)據(jù)類型,需實(shí)現(xiàn)深拷貝 book.articles = (ArrayList<String>) this.articles.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } return book; } @Override public String toString() { return "Book{" + "articles=" + articles + ", author='" + author + '\'' + ", price=" + price + ", publishers='" + publishers + '\'' + '}'; } }
/** * @author:TianLong * @date:2022/10/18 19:52 * @detail:客戶端 */ class Client { public static void main(String[] args) { ArrayList<String>arrayList=new ArrayList<>(); arrayList.add("丑小鴨"); arrayList.add("白雪公主"); arrayList.add("小紅帽"); Book book = new Book(arrayList,"安徒生",20,"人民出版社"); Book cloneBook = book.clone(); // 引用數(shù)據(jù)類型 book.articles.add("大鬧天宮"); // 數(shù)據(jù)輸出 System.out.println(book.toString()); System.out.println(cloneBook.toString()); } }
原型模式的優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn):在內(nèi)存中以二進(jìn)制流的方式直接拷貝對(duì)象數(shù)據(jù)。不需要new對(duì)象。
- 缺點(diǎn):clone創(chuàng)建對(duì)象時(shí),不會(huì)執(zhí)行構(gòu)造器函數(shù)。既是優(yōu)點(diǎn)也是缺點(diǎn)。如需要實(shí)現(xiàn)某些放在構(gòu)造器函數(shù)內(nèi)的操作時(shí),需要注意。
幾個(gè)注意事項(xiàng)
- 原型模式,只要能達(dá)到復(fù)制對(duì)象目的即可,不一定需要實(shí)現(xiàn)clone接口。
- 實(shí)現(xiàn)clone接口后,調(diào)用對(duì)象的clone方法時(shí),基本數(shù)據(jù)類型直接復(fù)制,引用數(shù)據(jù)類型只拷貝了對(duì)象引用。
- 若要實(shí)現(xiàn)引用數(shù)據(jù)類型的深拷貝,要么該引用數(shù)據(jù)類型自己內(nèi)部實(shí)現(xiàn)了clone接口,要么直接new該對(duì)象,將原有數(shù)據(jù)添加到new出來的對(duì)象中。手動(dòng)進(jìn)行數(shù)據(jù)拷貝。
- clone接口復(fù)制時(shí),參數(shù)內(nèi)容以二進(jìn)制流的方式在內(nèi)存中直接復(fù)制,不執(zhí)行對(duì)象的構(gòu)造方法。
后記
原型模式就像是在Ctrl+C和Ctrl+V一樣??梢詭臀覀兛焖俚脑趦?nèi)存中創(chuàng)建出一個(gè)對(duì)象。唯一要注意的是,拷貝出來的數(shù)據(jù)是 ”快捷方式“ ,還是一個(gè) ”單獨(dú)的文件“
以上就是java設(shè)計(jì)模式 Ctrl C和Ctrl V---原型模式的詳細(xì)內(nèi)容,更多關(guān)于java設(shè)計(jì)模式 Ctrl C Ctrl V-的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaWeb實(shí)現(xiàn)自動(dòng)登錄功能
這篇文章主要為大家詳細(xì)介紹了JavaWeb實(shí)現(xiàn)自動(dòng)登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08關(guān)于gradle多模塊項(xiàng)目依賴管理方式
這篇文章主要介紹了關(guān)于gradle多模塊項(xiàng)目依賴管理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04Java?Date(日期)對(duì)象進(jìn)行格式化的思路詳解
Date類是經(jīng)常會(huì)使用到的一個(gè)用來處理日期、時(shí)間的一個(gè)類。Date類是在java.util包下的Date類,這篇文章主要介紹了Java?Date(日期)對(duì)象如何進(jìn)行格式化呢,需要的朋友可以參考下2022-09-09java實(shí)現(xiàn)賬號(hào)登錄時(shí)發(fā)送郵件通知
這篇文章主要為大家詳細(xì)介紹了java如何實(shí)現(xiàn)在賬號(hào)登錄時(shí)發(fā)送郵件通知的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-09-09spring實(shí)現(xiàn)bean對(duì)象創(chuàng)建代碼詳解
這篇文章主要介紹了spring實(shí)現(xiàn)bean對(duì)象創(chuàng)建代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下2017-12-12