java設(shè)計模式Ctrl?C和Ctrl?V的原型模式詳解
記個筆記
早會,你拿著電腦在會議室里新建了一個記事本,用著搜狗輸入法,瘋狂的記錄著你們部門老大的各種會議紀(jì)要。
時間很快,等散會的時候已經(jīng)中午了,此時阿良才著急忙慌的趕到??粗肿銦o措的樣子,你淡定的對他說,不要急,會議內(nèi)容都被你記錄下來了,等會拷貝給他一份就好了。聽完你的話,他忐忑的心才慢慢放下。
我們?nèi)粘I钍褂秒娔X時,經(jīng)常會用到的一個操作,就是復(fù)制粘貼,即 Ctrl+C和Ctrl+V。但是編程中,我們創(chuàng)建了一個對象,想在使用時拷貝出來一份該怎么辦呢。這就是今天想提到的設(shè)計模式,原型模式。
原型模式定義
以目標(biāo)對象為原型實例,通過復(fù)制的方式創(chuàng)建新對象。
其實換成人話就是:在內(nèi)存里復(fù)制一個內(nèi)容一模一樣的新的對象。
使用的時機:
創(chuàng)建對象時,在構(gòu)造函數(shù)中會進(jìn)行大量的資源消耗操作。舉幾個比較夸張的例子:比如說可能進(jìn)行網(wǎng)絡(luò)申請或者說拷貝個幾百m的數(shù)據(jù)到本地,再或者說要檢查下本地內(nèi)存卡或者電腦硬盤上有多少個文件夾。這些都是很耗時的計算,但是這些都是在創(chuàng)建該對象之前的準(zhǔn)備工作(舉例而已,可能有點夸張)。此時可以使用原型模式,直接在內(nèi)存中復(fù)制一個一模一樣的對象。
拷貝的區(qū)別
官方抽象的描述
- 淺拷貝:基本數(shù)據(jù)類型互不干擾,兩個引用數(shù)據(jù)類型引用,指向內(nèi)存中同一個對象。
- 深拷貝:在內(nèi)存中生成一個內(nèi)容一模一樣的引用數(shù)據(jù)對象。原型對象和生成對象互不干擾。
好理解的人話
- 淺拷貝:你在我的電腦中,創(chuàng)建了一個C盤的快捷方式??旖莘绞胶臀业碾娔X中的C盤都能打開C盤文件夾。
- 深拷貝:你把你的會議時創(chuàng)建的記錄會議的記事本,拷貝了一份給你的好友阿良。這兩個記事本中的數(shù)據(jù)互不干擾。
使用的步驟:
1. 繼承實現(xiàn)Clone接口
2. 對象內(nèi)部的基本數(shù)據(jù)類型變量,會直接拷貝。
3. 引用數(shù)據(jù)類型,可以根據(jù)需求。自行實現(xiàn)深拷貝或者淺拷貝(默認(rèn)即淺拷貝,類比成快捷方式)
實現(xiàn)代碼
/** * @author:TianLong * @date:2022/10/18 19:47 * @detail:原型模式 具體實現(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ù)類型,需實現(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)缺點
- 優(yōu)點:在內(nèi)存中以二進(jìn)制流的方式直接拷貝對象數(shù)據(jù)。不需要new對象。
- 缺點:clone創(chuàng)建對象時,不會執(zhí)行構(gòu)造器函數(shù)。既是優(yōu)點也是缺點。如需要實現(xiàn)某些放在構(gòu)造器函數(shù)內(nèi)的操作時,需要注意。
幾個注意事項
- 原型模式,只要能達(dá)到復(fù)制對象目的即可,不一定需要實現(xiàn)clone接口。
- 實現(xiàn)clone接口后,調(diào)用對象的clone方法時,基本數(shù)據(jù)類型直接復(fù)制,引用數(shù)據(jù)類型只拷貝了對象引用。
- 若要實現(xiàn)引用數(shù)據(jù)類型的深拷貝,要么該引用數(shù)據(jù)類型自己內(nèi)部實現(xiàn)了clone接口,要么直接new該對象,將原有數(shù)據(jù)添加到new出來的對象中。手動進(jìn)行數(shù)據(jù)拷貝。
- clone接口復(fù)制時,參數(shù)內(nèi)容以二進(jìn)制流的方式在內(nèi)存中直接復(fù)制,不執(zhí)行對象的構(gòu)造方法。
后記
原型模式就像是在Ctrl+C和Ctrl+V一樣??梢詭臀覀兛焖俚脑趦?nèi)存中創(chuàng)建出一個對象。唯一要注意的是,拷貝出來的數(shù)據(jù)是 ”快捷方式“ ,還是一個 ”單獨的文件“
以上就是java設(shè)計模式 Ctrl C和Ctrl V---原型模式的詳細(xì)內(nèi)容,更多關(guān)于java設(shè)計模式 Ctrl C Ctrl V-的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java?Date(日期)對象進(jìn)行格式化的思路詳解
Date類是經(jīng)常會使用到的一個用來處理日期、時間的一個類。Date類是在java.util包下的Date類,這篇文章主要介紹了Java?Date(日期)對象如何進(jìn)行格式化呢,需要的朋友可以參考下2022-09-09spring實現(xiàn)bean對象創(chuàng)建代碼詳解
這篇文章主要介紹了spring實現(xiàn)bean對象創(chuàng)建代碼詳解,具有一定借鑒價值,需要的朋友可以參考下2017-12-12