1. 程式人生 > >如何理解原型模式中的深複製和淺複製

如何理解原型模式中的深複製和淺複製

    找工作之前製作簡歷時,需要做很多份簡歷,而且簡歷的格式是一樣的,也就意味著要做很多重複性的工作。在程式設計過程中,遇到重複性工作多的時候,貼上複製是最快的解決辦法。但是一旦這些程式碼需要修改時,那麼每一處用到這段程式碼的地方都需要進行修改,這也就增加了程式碼維護工作。在學習VB的時候,我們總是把相同的程式碼放在模組中,然後用到這段程式碼的地方就呼叫模組,這樣的話耦合性又是比較大的。那麼,解決這個問題到底該怎麼辦呢?

    設計模式中的原型模式就很好的解決了這個問題。原型模式是用原型例項指定建立物件的種類,並且通過拷貝這些原型建立的物件。

                         


    也就是說,先生成一份模板,然後其餘的物件都去拷貝這份模板,那麼得到的物件就都是一樣的了。

    下面小編就以簡歷複製為例子,簡單介紹原型模式:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">//工作經歷類
class WorkExperience {
	public String workDate;
	public String company;
}

//簡歷類
class Resume implements Cloneable{
	private String name;
	private String sex;
	private String age;
	
	private WorkExperience work;
	
	public Resume(String name){
		this.name=name;
		work=new WorkExperience;	
	}	
	
	//設定個人資訊
	public void SetPersonalInfo(String sex,String age){
			this.sex=sex;
			this.age=age;	
	}
	
	//設定工作經歷
	public void SetWorkExperience(String workDate,String company){
		work.workDate=workDate;
		work.company=company;	
	}
	
	public Object Clone(){
		return this.Clone();
	}
}

//客戶端
class WorkResume{
	public static void main(String[] args){
		Resume	a =new Resume("張三");
		a.SetPersonalInfo("男","20");
		a.SetWorkExperience("1998~2000","XX公司");
		Resume b=(Resume)a.Clone();
		b.SetWorkExperience("2000~2006","YY公司");
	}	
}</span></span>
    這樣設定完成之後得到的結果卻是兩條資訊是一樣的,而且工作經歷都是最新的這一條。

    做程式碼的記憶體分析,可得到如下圖:

                              

    即a、b兩個物件指向的是同一塊記憶體,也就是說b在進行修改時,a的資訊也會被修改,這也就是原型模式的淺複製。淺複製的意思就是說,只把物件a的引用複製給b,二者指向同一區域,當一個修改時,會影響另一個物件。

    對程式碼進行修改,將工作經歷類改為:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">//工作經歷類
class WorkExperience implements Cloneable{
	private String workDate;
	private String company;
	
  public Object Clone(){
	  WorkExperience obj=new WorkExperience();
	  obj.workDate=this.workDate;
	  obj.company=this.company;
	  return obj;		
  }
}</span></span>
將簡歷類中的Clone方法改為:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">	public Object Clone(){
		Resume obj=new Resume(this.work);
		obj.name=this.name;
		obj.sex=this.sex;
		obj.age=this.age;
		return obj;
	}</span></span>
並且在簡歷類中新增私有構造方法:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;">	private Resume(WorkExperience work){
		this.work=(WorkExperience)work.Clone();
	}	</span></span>
則得到的結果就是我們想要的結果了。

    對新程式碼進行記憶體分析,如下圖:
                         

    到此為止,原型模式的深淺複製就介紹完了,如果有什麼理解不到位的地方,歡迎廣大讀者給出指導。

總結

    深淺複製其實不難,只要把記憶體分析搞懂了就好了。淺複製是把一個物件的引用複製給另一個物件,二者對同一塊記憶體區域進行操作,類似於引數傳遞中的傳址。而深複製則是把原型物件的記憶體區域也複製一份給拷貝物件,二者各自擁有自己的引用,各自操作自己的記憶體區域,互不影響,類似於引數傳遞中的傳值。

相關推薦

原型模式克隆克隆

tin object bytearray supported 對象 gen object c rate 代碼 深克隆核心代碼: public Object deepclone () throws IOException, ClassNotFoundException{ /

如何理解原型模式複製複製

    找工作之前製作簡歷時,需要做很多份簡歷,而且簡歷的格式是一樣的,也就意味著要做很多重複性的工作。在程式設計過程中,遇到重複性工作多的時候,貼上複製是最快的解決辦法。但是一旦這些程式碼需要修改時

Javaclone方法以及複製複製

Java中處理基本資料型別(如:int , char , double等),都是採用按值傳遞的方式執行,除此之外的其他型別都是按照引用傳遞(傳遞的是一個物件的引用)的方式執行。物件在函式呼叫時和使用“=”賦值時都是引用傳遞。 Java中clone方法的作用是為了在現實程式

淺析Python拷貝拷貝

int lis end 四種 都是 變量 內存空間 string -- 按照以下不同情況,在IDE中逐個解除註釋,就明白了 import copy """ 第一種情況,不可變類型變量,都是引用 """ # a = 1 # a = (11, 222, 333) # a =

C 複製複製

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

談物件的複製複製的區別。

  場景   當你的元件裡需要用到同一個資料,但身負不同的責任。   舉個例子:vue的雙向繫結   你在與後端的互動中請求回來的資料,res,  let a = res; let b = res;  因為是會用到checkbox,在外層的列表裡選中資

javascript的複製複製(深度拷貝拷貝)

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>js深度複製淺顯複製</title> </head>

ES6(JavaScript)的複製複製

React中,我們會遇到一個有趣的問題,那就是物件的複製,為什麼說有趣,是因為直覺和結果差距很大。 我們看一下這個例子: let a={tile:'深複製'}; let b=a; a.title='淺複製'; 那麼我們會獲得兩個物件,一個a,一個b,a的title是淺複製,

題目筆記(閉包,複製複製,原生js實現Promise)

就面試筆試題的一些筆記: 閉包( 實現add(2)(5) ) 深複製和淺複製 原生js實現Promise △ –>閉包知識: 實現add(2)(5) function add (x) { return functio

Java物件的複製複製

原文連結 我們在編碼過程經常會碰到將一個物件傳遞給另一個物件,java中對於基本型變數採用的是值傳遞,而對於物件比如bean傳遞時採用的引用傳遞也就是地址傳遞,而很多時候對於物件傳遞我們也希望能夠象值傳遞一樣,使得傳遞之前和之後有不同的記憶體地址,在這種情況下

Java拷貝拷貝(deepcopyshallowcopy)

原型模式要求用深拷貝(複製/克隆)的方式實現,對這個概念很模糊。在自己查了相關資料後,我將從三個方面講述深淺拷貝: 圖形表述深淺拷貝區別及特點 Object類中的clone()方法實現深淺拷貝 實際應用中深淺拷貝區別 一 圖形表述深淺拷貝區別及特點 前提:深淺拷貝基本

面試:C++的複製複製(轉)

物件的構造,也可以由複製建構函式完成,即用一個物件的內容去初始化另一個物件的內容。此時,若物件使用了堆空間(注意和“堆物件”區分),就有深、淺複製的問題,不清楚則很容易出錯。 什麼是淺複製 預設複製建構函式:用一個物件的內容初始化另一個同類物件,也稱為預設的

C 複製複製

                物件的複製   對於普通型別的物件來說,它們之間的複製是很簡單的,例如:int a=88;int b=a;double f=3.12;double d(f);  而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種資料成員。下面看一個類物件複製的簡單例子。#includ

關於C#拷貝拷貝的認識

首先說我理解的一些基本概念(若有不對,歡迎指點) 記憶體:用來儲存程式資訊的介質。 指標:指向一塊記憶體區域,通過它可以訪問該記憶體區域中儲存的程式資訊。(C#也是有指標的) 值型別:struct(整形、浮點型、decimal的內部實現都是struct)、enum、可空型別

從底層分析python拷貝拷貝區別

深淺拷貝在python中經常使用,其區別的外在表現是:使用淺拷貝,當原容器物件中可變物件中有元素髮生變化,拷貝得到的物件也會變化。而使用深拷貝時,不會有這種問題。聽起來有一點難理解,看例子比較直觀:淺拷貝>>> list1 = [['a', 'b'], 1,

python拷貝拷貝的區別

賦值語句的是記憶體地址引用,不是拷貝拷貝是匯入copy包,分copy和deepcopy兩種,即淺拷貝和深拷貝對於非巢狀資料         copy.copy 和 copy.deepcopy 沒有區別 都會開闢新空間 儲存資料

C++複製複製

物件的複製   對於普通型別的物件來說,它們之間的複製是很簡單的,例如:int a=88; int b=a; double f=3.12; double d(f);  而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種資料成員。下面看一個類物件複製的簡單例子。#in

python的複製複製

# -*- coding:UTF-8 -*- #此次練習主要是討論物件的淺複製和深複製 import copy #淺複製一個object有三種方式:1、slice操作; # 2、copy模組的copy函式; #

低門檻徹底理解JavaScript拷貝拷貝

規範 數據類型 ash 隨著 array 賦值 mbo 進行 函數 作者 | 吳勝斌 來源 | https://www.simbawu.com/article/search/9 在說深拷貝與淺拷貝前,我們先看兩個簡單的案例: //案例1var num1 =

徹底理解JavaScript拷貝拷貝

在說深拷貝與淺拷貝前,我們先看兩個簡單的例項: //案例1 var num1 = 1, num2 = num1; console.log(num1) //1 console.log(num2) //1 num2 = 2; //修改num2 console.lo