設計模式 原型模式

2021-10-08 10:42:27 字數 3964 閱讀 8308

用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。

先上**:

定義乙個person類,實現cloneable介面,重寫clone()方法

public

class

person

implements

cloneable

@override

protected person clone()

catch

(clonenotsupportedexception e)

return p;

}@override

public string tostring()

';}}

客戶端呼叫:

public

class

client

system.out.

println

("p2:"

+p2.

tostring()

);//p2:person

}}

輸出與預想一致,拷貝成功!

再person類中再加乙個引用型別的成員變數location,**如下:

person跟location類:

public

class

person

implements

cloneable

public

void

setlocation

(location location)

public

person

(string name,

int age, location location)

@override

protected person clone()

catch

(clonenotsupportedexception e)

return p;

}@override

public string tostring()

';}}

class

location

@override

public string tostring()

';}}

客戶端:

public

class

client

}輸出:

false

p1:person

},location hashcode:

460141958

p2:person

},location hashcode:

460141958

可以看出,location的hashcode值相等,說明是同乙個物件,其實想想也對,person複製物件的時候會把location屬性也複製,但是複製的肯定是引用,複製的引用指向了原來的location物件。

對於資料型別是基本資料(包括string)型別的成員變數,淺拷貝會直接進行值傳遞,也就是將該屬性值複製乙份給新的物件。

對於資料型別是引用資料型別的成員變數,比如說成員變數是某個陣列、某個類的物件等,那麼淺拷貝會進行引用傳遞,也就是只是將該成員變數的引用值(記憶體位址)複製乙份給新的物件。因為實際上兩個物件的該成員變數都指向同乙個例項。在這種情況下,在乙個物件中修改該成員變數會影響到另乙個物件的該成員變數值

想要使得上述的location物件也拷貝乙份,然後person物件的成員變數指向新的location物件,就需要深拷貝。

方法也很簡單,讓location也實現cloneable介面,重新clone()方法,在person clone() 中呼叫location的clone() 即可,其實就是把每個物件都clone() 了一遍。

**如下:

person和location類:

public

class

person

implements

cloneable

public

void

setlocation

(location location)

public

person

(string name,

int age, location location)

@override

protected person clone()

catch

(clonenotsupportedexception e)

return p;

}@override

public string tostring()

';}}

class

location

implements

cloneable

@override

protected object clone()

throws clonenotsupportedexception

@override

public string tostring()

';}}

client:

public

class

client

}輸出:

false

p1:person

},location hashcode:

460141958

p2:person

},location hashcode:

1163157884

深拷貝成功,但是如果person物件特別複雜,其中有很多引用型別的成員變數,那就很麻煩。

還有一種深拷貝,序列化。

**:persion和location類:

public

class

person

implements

serializable

public

void

setlocation

(location location)

public

person

(string name,

int age, location location)

public person deepclone()

catch

(exception e)

finally

catch

(exception e2)}}

@override

public string tostring()

';}}

class

location

implements

serializable

@override

public string tostring()

';}}

client:

public

class

client

}輸出:

false

p1:person

},location hashcode:

325040804

p2:person

},location hashcode:

1595428806

建立新的物件比較複雜時,可以利用原型模式簡化物件的建立過程,同時也能夠提高效率,簡單的物件new的效率比clone高

不用重新初始化物件,而是動態地獲得物件執行時的狀態

如果原始物件發生變化(增加或者減少屬性),其它轉殖物件的也會發生相應的變化,無需修改**

在實現深轉殖的時候可能需要比較複雜的**

缺點:需要為每乙個類配備乙個轉殖方法,這對全新的類來說不是很難,但對已有的類進行改造時,需要修改其源**,違背了 ocp 原則,這點請同學們注意.

設計模式 原型模式

1.首先分析原型模式的由來 一般來說,建立乙個物件可以由以下方法 知道物件的具體型別,直接用new生成。不知道型號,知道相應的需求,可以使用工廠方法模式。根據乙個已有的物件來複製為乙個新的物件,可以使用原型模式。2.原型模式可以簡單理解為拷貝原型物件得到新的物件。想象乙個配鑰匙的小店,給店主乙個原有...

設計模式 原型模式

魔術師手拿一張百元大鈔,瞬間又變出兩張。也像配鑰匙一樣,拿一把鑰匙,老師傅就能做出另乙個一模一樣的。像這種複製我們並不陌生,類似於我們設計中的原型模式 本文將從以下幾點 原型模式 概述 結構圖 淺複製深複製 總結 用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。允許乙個物件再建立另外...

設計模式 原型模式

原型模式 用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。1 假設我們現有乙個物件,但是它的型別需要執行期確定,我們不知道它的動態型別是什麼,現在我們想建立它的副本。顯然通過建構函式建立是很麻煩的,這時候我們可以使用原型模式中的clone函式直接得到該物件的副本。2 有些時候我們想要...