日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

【设计模式】原型模式 ( 浅拷贝 | 深拷贝 | 原型与单例冲突 | 禁用 final )

發布時間:2025/6/17 asp.net 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【设计模式】原型模式 ( 浅拷贝 | 深拷贝 | 原型与单例冲突 | 禁用 final ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

        • I . 原型模式 總結
        • II . 原型模式 淺拷貝
        • III . 原型模式 深拷貝
        • IV . 原型模式 與 單例
        • V . 原型模式 中的 final 關鍵字 ( 禁止出現 )



I . 原型模式 總結



1 . 原型模式本質及性能 : 原型模式使用 clone 方法克隆對象 , 其本質是在內存中拷貝二進制數據 , 這種方式要比調用 new 構造函數性能高得多 ;


2 . clone 核心是內存拷貝 : clone 對象不使用復用原有對象 , 是在內存中的另一個地址空間復制了一份一模一樣的數據 , 然后將其首地址給新對象的引用 ;


3 . 原型模式適用場景 : ① 節省資源 ( 內存 CPU 硬件等 ) , ② 構造函數復雜 ( 計算繁瑣 耗時 ) , ③ 創建大量對象 ;


4 . 原型模式實現 : 原型模式類實現 Cloneable 接口 , 實現其中的 clone 方法 ;


① 淺拷貝實現 : 淺拷貝默認調用 super.clone ;

② 深拷貝實現 : 深拷貝需要調用 每個引用成員對象的 clone 方法創建成員對象 , 然后賦值給新的原型模式創建的對象 , 作為其中的成員 ;


5 . 注意拷貝方式 : 默認淺拷貝 , 如果類中有引用類型成員變量 , 需要考慮深拷貝問題 , 可能會出現多個對象持有同一個引用變量 ;



II . 原型模式 淺拷貝



1 . 淺拷貝 : 調用 clone 對象拷貝內存中的數據時 , 要注意拷貝的是基礎數據類型 , 對于數組 , 集合 , 自定義類等引用數據類型僅拷貝地址 , 會造成所有的對象都持有同一個內存地址的引用成員 ;


① 基礎數據類型 : 如果類中全部是基礎數據類型 , 使用 clone 可以將該類完整的復制一份 ;

② 引用數據類型 : 如果類中有引用類型成員 , 只是拷貝該成員的地址 , 所有的拷貝創建的原型模式實例對象都持有同一個引用 , 如果修改該引用成員的值 , 所有的原型對象實例的值都會跟著修改 ;


2 . 淺拷貝示例 :


① 原型模式類 Student : 該類中持有 Vector<String> courses 引用數據類型 , 調用 clone 方法在內存中復制對象時 , 僅復制了對象的地址 , 即將該引用的地址賦值給了 clone 出的對象 ;

package kim.hsl.design.prototype.shallowcopy;import java.util.Vector;/*** 淺拷貝示例*/ public class Student implements Cloneable {private String name;private int age;//該類在拷貝時 , 如果使用淺拷貝 , 只是將地址拷貝走了 , 兩個對象實際上用的是同一個對象private Vector<String> courses = new Vector<>();public Student() {System.out.println("調用 Student 默認構造函數");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Vector<String> getCourses() {return courses;}public void setCourses(Vector<String> courses) {this.courses = courses;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", courses=" + courses +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {System.out.println("調用 Student clone 方法");return super.clone();} }

② 測試類 Main : 此處創建了兩個 Student 實例對象 , 但是兩個對象都持有同一個 Vector<String> courses 引用數據類型成員 , 當修改其中一個成員時 , 兩個對象中的該成員都會改變 ;

package kim.hsl.design.prototype.shallowcopy;public class Main {public static void main(String[] args) {try {//測試使用 clone 方法實現的原型模式 , 使用原型模式創建 2 個對象Student newStudent = new Student();// 1 . 使用 clone 方法創建對象1Student student = (Student) newStudent.clone();student.setName("Tom");student.setAge(10);student.getCourses().add("數學");// 2 . 使用 clone 方法創建對象2Student student2 = (Student) newStudent.clone();student2.setName("Jerry");student2.setAge(18);student2.getCourses().add("語文");System.out.println("student : " + student + "\nstudent2 : " + student2);} catch (CloneNotSupportedException e) {//捕獲 clone 方法可能產生的異常e.printStackTrace();}} }

③ 執行結果 : 調用第一個對象 add 方法 , 在 vector 集合中添加了 “數學” 字符串 , 調用第二個對象的 add 方法 , 向 courses 集合中添加 “語文” 字符串 , 理論上兩個分別是 “數學” 和 “語文” , 但是此處卻都變成了 “數學” “語文” 兩個課程 , 說明兩個原型模式對象持有的 Vector<String> courses 變量是指向同一個內存地址的 ;

調用 Student 默認構造函數 調用 Student clone 方法 調用 Student clone 方法 student : Student{name='Tom', age=10, courses=[數學, 語文]} student2 : Student{name='Jerry', age=18, courses=[數學, 語文]}

III . 原型模式 深拷貝



1 . 深拷貝策略 : 深拷貝時需要在 clone 方法中 , 調用引用數據類型本身的 clone 對象 , 在將其賦值給被拷貝的原型模式實例對象 ;


2 . 深拷貝 clone 方法流程 :


① 創建實例對象 : 通過 clone 方法 , 創建原型模式類的實例對象 , 此時該對象的引用成員處于淺拷貝狀態 ;

② 拷貝引用成員 : 調用原型模式類對象成員的 clone 對象 , 創建新的成員對象 , 將新的成員對象賦值給克隆出的原型模式對象 ;

③ 返回新的對象 : 返回 clone 創建的原型模式實例對象 ;


3 . 示例代碼 :


① 原型模式深拷貝示例 : 深拷貝與淺拷貝只是在 clone 方法中表現不同 , 其它代碼一致 ; 在 clone 方法中需要針對引用類型進行克隆 ;

package kim.hsl.design.prototype.deepcopy;import java.util.Vector;/*** 淺拷貝示例*/ public class Student implements Cloneable {private String name;private int age;//該類在拷貝時 , 如果使用淺拷貝 , 只是將地址拷貝走了 , 兩個對象實際上用的是同一個對象private Vector<String> courses = new Vector<>();public Student() {System.out.println("調用 Student 默認構造函數");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Vector<String> getCourses() {return courses;}public void setCourses(Vector<String> course) {this.courses = course;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", course=" + courses +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {System.out.println("調用 Student clone 方法");//1 . 首先拷貝一個基本對象Student student = (Student) super.clone();//2 . 將引用類型的對象單獨克隆賦值student.courses = (Vector<String>) this.courses.clone();//3 . 返回創建的新的對象return student;} }

② 測試代碼 :

package kim.hsl.design.prototype.deepcopy;public class Main {public static void main(String[] args) {try {//測試使用 clone 方法實現的原型模式 , 使用原型模式創建 2 個對象Student newStudent = new Student();// 1 . 使用 clone 方法創建對象1Student student = (Student) newStudent.clone();student.setName("Tom");student.setAge(10);student.getCourses().add("數學");// 2 . 使用 clone 方法創建對象2Student student2 = (Student) newStudent.clone();student2.setName("Jerry");student2.setAge(18);student2.getCourses().add("語文");System.out.println("student : " + student + "\nstudent2 : " + student2);} catch (CloneNotSupportedException e) {//捕獲 clone 方法可能產生的異常e.printStackTrace();}} }

③ 運行結果 : 原型模式的兩個實例對象的互不干擾 ;


調用 Student 默認構造函數 調用 Student clone 方法 調用 Student clone 方法 student : Student{name='Tom', age=10, course=[數學]} student2 : Student{name='Jerry', age=18, course=[語文]}

IV . 原型模式 與 單例



1 . 原型模式 與 單例模式 :


① 原型模式 : 原型模式的核心是不調用構造函數 , 使用 clone 方法在內存中克隆對象 ;

② 單例模式 : 單例模式的核心是私有化構造函數 , 控制外部用戶 , 不能隨意調用構造函數創建對象 ;


2 . Cloneable 破壞了單例模式 : 此處二者就出現了矛盾 , 如果單例類 , 實現了 Cloneable 接口 , 那么該類就可以調用 clone 方法創建另外的實例對象 , 因此破壞了單例模式 ;


3 . 解決方案 :

① 不實現 Cloneable 接口 : 單例模式中不要實現 Cloneable 接口 , 不提供內存拷貝功能 ;

② clone 中調用單例 : 如果必須實現 Cloneable 接口 , 那么在重寫的 clone 方法中 , 調用獲取單例類的方法 , 不要進行內存對象拷貝創建新的實例對象 ;



V . 原型模式 中的 final 關鍵字 ( 禁止出現 )



1 . final 作用 : final 用于修飾常量 , 被 final 修飾的變量無法重新賦值 ;


2 . Cloneable 實現類成員不要使用 final : 在原型模式的類中 , 實現了 Cloneable 接口 , 重寫了 clone 方法 , 其類對象的成員不能被 final 修飾 , 否則無法重新賦值 ;

總結

以上是生活随笔為你收集整理的【设计模式】原型模式 ( 浅拷贝 | 深拷贝 | 原型与单例冲突 | 禁用 final )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。