創建型模式-原型模式

文章目錄

  • 一、原型模式
    • 1. 概述
    • 2. 結構
    • 3. 實現
    • 4. 案例
    • 1.5 使用場景
    • 1.6 擴展(深克隆)

一、原型模式

1. 概述

用一個已經創建的實例作為原型,通過復制該原型對象來創建一個和原型對象相同的新對象。

2. 結構

原型模式包含如下角色:

  • 抽象原型類:規定了具體原型對象必須實現的 clone() 方法。
  • 具體原型類:實現抽象原型類的 clone() 方法,它是可被復制的對象。
  • 訪問類:使用具體原型類中的 clone() 方法來復制新的對象。

接口類圖如下:

在這里插入圖片描述

3. 實現

原型模式的克隆分為淺克隆和深克隆。

淺克隆:創建一個新對象,新對象的屬性和原來對象完全相同,對于非基本類型屬性,仍指向原有屬性所指向的對象的內存地址。
深克隆:創建一個新對象,屬性中引用的其他對象也會被克隆,不再指向原有對象地址。

Java中的Object類中提供了 clone() 方法來實現淺克隆。 Cloneable 接口是上面的類圖中的抽象原型類,而實現了Cloneable接口的子實現類就是具體的原型類。

Realizetype(具體的原型類):

public class Realizetype implements Cloneable {public Realizetype() {System.out.println("具體的原型對象創建完成!");}@Overridepublic Realizetype clone() throws CloneNotSupportedException {System.out.println("具體原型復制成功!");return (Realizetype) super.clone();}
}

PrototypeTest(測試訪問類):

public class PrototypeTest {public static void main(String[] args) throws CloneNotSupportedException {//創建一個原型類對象Realizetype realizetype = new Realizetype();//調用Realizetype類中的clone方法進行對象的克隆Realizetype clone = realizetype.clone();System.out.println("原型對象和克隆出來的是否是同一個對象?" + (realizetype == clone));}
}

運行結果為:
在這里插入圖片描述

4. 案例

用原型模式生成“三好學生”獎狀

同一學校的“三好學生”獎狀除了獲獎人姓名不同,其他都相同,可以使用原型模式復制多個“三好學生”獎狀出來,然后在修改獎狀上的名字即可。

在這里插入圖片描述

獎狀類:

public class Citation implements Cloneable {private String name;public void setName(String name) {this.name = name;}public String getName() {return (this.name);}public void show() {System.out.println(name + "同學:在2020學年第一學期中表現優秀,被評為三好學生。特發此狀!");}@Overridepublic Citation clone() throws CloneNotSupportedException {return (Citation) super.clone();}
}

測試訪問類:

public class CitationTest {public static void main(String[] args) throws CloneNotSupportedException {Citation c1 = new Citation();c1.setName("張三");//復制獎狀Citation c2 = c1.clone();//將獎狀的名字修改李四c2.setName("李四");c1.show();c2.show();}
}

運行結果為:
在這里插入圖片描述

1.5 使用場景

  • 對象的創建非常復雜,可以使用原型模式快捷的創建對象。
  • 性能和安全要求比較高。

1.6 擴展(深克隆)

將上面的“三好學生”獎狀的案例中Citation類的name屬性修改為Student類型的屬性。

獎狀類:

public class Citation implements Cloneable {private Student stu;public Student getStu() {return stu;}public void setStu(Student stu) {this.stu = stu;}void show() {System.out.println(stu.getName() + "同學:在2020學年第一學期中表現優秀,被評為三好學生。特發此狀!");}@Overridepublic Citation clone() throws CloneNotSupportedException {return (Citation) super.clone();}
}

學生類:

public class Student {private String name;private String address;public Student(String name, String address) {this.name = name;this.address = address;}public Student() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}

測試類:

public class CitationTest {public static void main(String[] args) throws CloneNotSupportedException {Citation c1 = new Citation();Student stu = new Student("張三", "西安");c1.setStu(stu);//復制獎狀Citation c2 = c1.clone();//獲取c2獎狀所屬學生對象Student stu1 = c2.getStu();stu1.setName("李四");//判斷stu對象和stu1對象是否是同一個對象System.out.println("stu和stu1是同一個對象?" + (stu == stu1));c1.show();c2.show();}
}

運行結果為:
在這里插入圖片描述

說明:
? stu對象和stu1對象是同一個對象,就會產生將stu1對象中name屬性值改為“李四”,兩個Citation(獎狀)對象中顯示的都是李四。這就是淺克隆的效果,對具體原型類(Citation)中的引用類型的屬性進行引用的復制。這種情況需要使用深克隆,而進行深克隆需要使用對象流。

public class CitationTest1 {public static void main(String[] args) throws Exception {Citation c1 = new Citation();Student stu = new Student("張三", "西安");c1.setStu(stu);//創建對象輸出流對象ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Think\\Desktop\\b.txt"));//將c1對象寫出到文件中oos.writeObject(c1);oos.close();//創建對象出入流對象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\Think\\Desktop\\b.txt"));//讀取對象Citation c2 = (Citation) ois.readObject();//獲取c2獎狀所屬學生對象Student stu1 = c2.getStu();stu1.setName("李四");//判斷stu對象和stu1對象是否是同一個對象System.out.println("stu和stu1是同一個對象?" + (stu == stu1));c1.show();c2.show();}
}

運行結果為:
在這里插入圖片描述
注意:Citation類和Student類必須實現Serializable接口,否則會拋NotSerializableException異常。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/36498.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36498.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36498.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

微服務架構和分布式架構的區別

微服務架構和分布式架構的區別 有:1、含義不同;2、概念層面不同;3、解決問題不同;4、部署方式不同;5、耦合度不同。其中,含義不同指微服務架構是一種將一個單一應用程序開發為一組小型服務的方法&#xff…

使用windows搭建WebDAV服務,并內網穿透公網訪問【無公網IP】

文章目錄 1. 安裝IIS必要WebDav組件2. 客戶端測試3. 使用cpolar內網穿透,將WebDav服務暴露在公網3.1 打開Web-UI管理界面3.2 創建隧道3.3 查看在線隧道列表3.4 瀏覽器訪問測試 4. 安裝Raidrive客戶端4.1 連接WebDav服務器4.2 連接成功4.2 連接成功 1. Linux(centos8…

【Vue-Router】路由入門

路由(Routing)是指確定網站或應用程序中特定頁面的方式。在Web開發中,路由用于根據URL的不同部分來確定應用程序中應該顯示哪個內容。 構建前端項目 npm init vuelatest //或者 npm init vitelatest安裝依賴和路由 npm install npm instal…

TCP重連 - 筆記

1 C++ TCP/IP 關于tcp斷線重連的問題 C++ TCP/IP 關于tcp斷線重連的問題_c++ 斷線重連_Bug&猿柒。的博客-CSDN博客 2 C++基礎--完善Socket C/S ,實現客戶端,服務器端斷開重連 https://www.cnblogs.com/kingdom_0/articles/2571727.html 3 C++實現Tcp通信(考慮客戶…

ATF BL1 UFS初始化簡單分析

ATF BL1 UFS初始化分析 1 ATF的下載鏈接2 ATF BL1 UFS 初始化簡易流程圖3 ATF BL1 ufs初始化簡單過程分析3.1 調用過程3.2 hikey960_ufs_init3.3 dw_ufs_init3.3 ufs_init 以海思hikey960為例來介紹,簡單介紹在ATF BL1階段的初始化處理。 1 ATF的下載鏈接 https:/…

藍帽杯 取證2022

網站取證 網站取證_1 下載附件 并解壓 得到了一個文件以及一個壓縮包 解壓壓縮包 用火絨查病毒 發現后門 打開文件路徑之后 發現了一句話木馬 解出flag 網站取證_2 讓找數據庫鏈接的明文密碼 打開www文件找找 查看數據庫配置文件/application/database.php(CodeI…

Vue3.2+TS的父傳子,子傳父

這是父組件 <template><div><!-- 這個fn是子組件emit觸發名&#xff0c;兩邊保持一致 --><Child :num"num" fn"numUp"></Child></div> </template><script setup lang"ts"> import { ref } fr…

截止到目前全量主體總數有多少?

企業主體類型 企業主體類型有很多種&#xff0c;一般我們會分為公司&#xff08;有限責任&#xff09;、合伙企業、個人獨資企業、個體經營戶這些類別。 今天我們按照企業&#xff0c;個體&#xff0c;組織的分類方式來看各個主體的總數。 企業&#xff1a;統一社會信用代碼…

基于IP網絡的存儲協議——iSCSI

文章首發地址 iSCSI&#xff08;Internet Small Computer System Interface&#xff09;是一種基于IP網絡的存儲協議&#xff0c;它能夠在TCP/IP網絡上實現SCSI協議&#xff0c;使得不同的主機可以通過網絡共享存儲設備。iSCSI可以將存儲設備映射到本地主機上&#xff0c;使得主…

ARTS 挑戰打卡的第7天 --- Ubuntu中的WindTerm如何設置成中文,并且關閉shell中Tab鍵聲音(Tips)

前言 &#xff08;1&#xff09;Windterm是一個非常優秀的終端神器。關于他的下載我就不多說了&#xff0c;網上很多。今天我就分享一個國內目前沒有找到的這方面的資料——Ubuntu中的WindTerm如何設置成中文&#xff0c;并且關閉shell中Tab鍵聲音。 將WindTerm設置成中文 &…

【Mac】mac 系統下格式化U盤或移動硬盤為ext4格式

1. 打開終端&#xff0c;安裝 homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"2. 安裝之后再次運行此命令 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"…

學習C++資料集合

學習C C 是一個難學易用的語言&#xff01; C 的難學&#xff0c;不僅在其廣博的語法&#xff0c;以及語法背後的語意&#xff0c;以及語意背後的深層思維&#xff0c;以及深層思維背後的物件模型&#xff1b; C 的難學&#xff0c;還在於它提供了四種不同&#xff08;但相輔相…

第五十三天

●剪輯——Pr 剪輯(Film editing)&#xff0c;即將影片制作中所拍攝的大量素材&#xff0c;經過選擇、取舍、分解與組接&#xff0c;最終完成一個連貫流暢、含義明確、主題鮮明并有藝術感染力的作品。 ?線性編輯 將素材按時間順序連接成新的連續畫面的技術 ?非線性編輯 …

Unity zSpace 開發

文章目錄 1.下載 zSpace 開發環境1.1 zCore Unity Package1.2 zView Unity Package 2. 導入工程3. 發布設置4.功能實現4.1 用觸控筆來實現對模型的拖拽&#xff1a; 5. 后續更新 1.下載 zSpace 開發環境 官網地址 1.1 zCore Unity Package zSpace 開發核心必須 1.2 zView …

MyBatis EntityWrapper DISTINCTQU用法

使用EntityWrapper進行DISTINCT查詢可以通過以下幾個步驟實現&#xff1a; 創建一個EntityWrapper對象&#xff1a;EntityWrapper<T> wrapper new EntityWrapper<>();使用setSqlSelect方法設置需要查詢的字段&#xff0c;并在字段前加上DISTINCT關鍵字&#xff0…

機器人CPP編程基礎-05完結The End

非常不可思議……之前四篇博文竟然有超過100的閱讀量…… 此文此部分終結&#xff0c;沒有繼續寫下去的必要了。 插入一個分享&#xff1a; 編程基礎不重要了&#xff0c;只要明確需求&#xff0c;借助AI工具就能完成一個項目。 當然也不是一次成功&#xff0c;工具使用也需要…

ORA-01539: 表空間 ‘GSC004‘ 未聯機

1.檢查表空間狀態&#xff1a; SELECT tablespace_name, status FROM dba_tablespaces WHERE tablespace_name GSC004;2.聯機表空間&#xff1a;如果表空間處于離線狀態&#xff0c;可以嘗試將其聯機。 ALTER TABLESPACE GSC004 ONLINE;3.檢查表空間文件&#xff0c;確保表空…

代碼隨想錄第48天 | 198. 打家劫舍、213. 打家劫舍II、337. 打家劫舍III

198. 打家劫舍 當前房屋偷與不偷取決于 前一個房屋和前兩個房屋是否被偷了。 遞歸五部曲&#xff1a; dp[i]&#xff1a;考慮下標i&#xff08;包括i&#xff09;以內的房屋&#xff0c;最多可以偷竊的金額為dp[i]。決定dp[i]的因素就是第i房間偷還是不偷。 如果偷第i房間&…

計算機視覺一 —— 介紹與環境安裝

傲不可長 欲不可縱 樂不可極 志不可滿 一、介紹 研究理論和應用 - 研究如何使機器“看”的科學 - 讓計算機具有人類視覺的所有功能 - 讓計算機從圖像中&#xff0c;提取有用的信息&#xff0c;并解釋 - 重構人眼&#xff1b;重構視覺皮層&#xff1b;重構大腦剩余部分 計…

利用ChatGPT繪制思維導圖——以新能源汽車競品分析報告為例

隨著人們對環境保護的日益關注和傳統燃油汽車的限制&#xff0c;全球范圍內對新能源汽車的需求不斷增長。新能源汽車市場的激烈競爭使得了解各個競品的特點和優劣成為關鍵。然而&#xff0c;針對這一領域的詳盡競品分析卻常常需要大量時間和精力。 在此背景下&#xff0c;人工智…