java設(shè)計(jì)模式Ctrl?C和Ctrl?V的原型模式詳解
記個(gè)筆記
早會(huì),你拿著電腦在會(huì)議室里新建了一個(gè)記事本,用著搜狗輸入法,瘋狂的記錄著你們部門老大的各種會(huì)議紀(jì)要。
時(shí)間很快,等散會(huì)的時(shí)候已經(jīng)中午了,此時(shí)阿良才著急忙慌的趕到。看著他手足無(wú)措的樣子,你淡定的對(duì)他說(shuō),不要急,會(huì)議內(nèi)容都被你記錄下來(lái)了,等會(huì)拷貝給他一份就好了。聽完你的話,他忐忑的心才慢慢放下。
我們?nèi)粘I钍褂秒娔X時(shí),經(jīng)常會(huì)用到的一個(gè)操作,就是復(fù)制粘貼,即 Ctrl+C和Ctrl+V。但是編程中,我們創(chuàng)建了一個(gè)對(duì)象,想在使用時(shí)拷貝出來(lái)一份該怎么辦呢。這就是今天想提到的設(shè)計(jì)模式,原型模式。
原型模式定義
以目標(biāo)對(duì)象為原型實(shí)例,通過(guò)復(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è)比較夸張的例子:比如說(shuō)可能進(jìn)行網(wǎng)絡(luò)申請(qǐng)或者說(shuō)拷貝個(gè)幾百m的數(shù)據(jù)到本地,再或者說(shuō)要檢查下本地內(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出來(lái)的對(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ì)象。唯一要注意的是,拷貝出來(lái)的數(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è)計(jì)中filter粗粒度權(quán)限控制代碼示例
這篇文章主要介紹了javaweb設(shè)計(jì)中filter粗粒度權(quán)限控制代碼示例,小編覺(jué)得還是挺不錯(cuò)的,需要的朋友可以參考。2017-10-10
使用spring-task定時(shí)任務(wù)動(dòng)態(tài)配置修改執(zhí)行時(shí)間
這篇文章主要介紹了使用spring-task定時(shí)任務(wù)動(dòng)態(tài)配置修改執(zhí)行時(shí)間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java中成員方法與成員變量訪問(wèn)權(quán)限詳解
在Java學(xué)習(xí)過(guò)程中,在寫類經(jīng)常為用到public,private和protected,我個(gè)人的經(jīng)驗(yàn)是一般類的成員變量都是用private,方法用public,類的內(nèi)部用protected方法,如果是存在子類的,那我就會(huì)把父類中的成員變量變?yōu)閜rotected。(其余的看具體實(shí)際情 況而定)2015-08-08
Java將json字符串轉(zhuǎn)換為數(shù)組的幾種方法
在Java開發(fā)中,經(jīng)常會(huì)遇到將json字符串轉(zhuǎn)換為數(shù)組的需求,本文主要介紹了Java將json字符串轉(zhuǎn)換為數(shù)組的幾種方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
SpringBoot?多環(huán)境打包最佳實(shí)踐記錄
SpringBoot通過(guò)配置多環(huán)境文件和在打包時(shí)指定激活的環(huán)境,實(shí)現(xiàn)多環(huán)境打包與部署,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-11-11
spring mvc DispatcherServlet之前端控制器架構(gòu)詳解
這篇文章主要為大家詳細(xì)介紹了spring mvc DispatcherServlet之前端控制器架構(gòu),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
SpringMVC JSON數(shù)據(jù)交互實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了SpringMVC JSON數(shù)據(jù)交互實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
dm.jdbc.driver.DMException網(wǎng)絡(luò)通信異常的解決過(guò)程
最近一個(gè)項(xiàng)目里面出現(xiàn)了一個(gè)比較詭異的問(wèn)題,給大家分享下,這篇文章主要給大家介紹了關(guān)于dm.jdbc.driver.DMException網(wǎng)絡(luò)通信異常的解決過(guò)程,需要的朋友可以參考下2023-02-02
Java8中Stream使用的一個(gè)注意事項(xiàng)
最近在工作中發(fā)現(xiàn)了對(duì)于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個(gè)非常重要的注意點(diǎn),所以這篇文章主要給大家介紹了關(guān)于Java8中Stream使用過(guò)程中的一個(gè)注意事項(xiàng),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11

