《大話設計模式》 原型模式

2021-10-03 08:00:27 字數 3858 閱讀 3347

如果物件的建立成本比較大,而同乙個類的不同物件之間差別不大(大部分欄位都相同),在這種情況下,我們可以利用對已有物件(原型)進行複製(或者叫拷貝、轉殖)的方式,來建立新物件,以達到節省建立時間的目的。這種基於原型來建立物件的方式就叫作原型設計模式,簡稱原型模式

核心:拷貝(轉殖)

建立物件包含的申請記憶體、給成員變數賦值這一過程,本身並不會花費太多時間,對於大部分業務系統來說,這點時間完全是可以忽略的。

但是,如果物件中的資料需要經過複雜的計算才能得到(比如排序、計算雜湊值),或者需要從 rpc、網路、資料庫、檔案系統等非常慢速的 io 中讀取,這種情況下,我們就可以利用原型模式,從其他已有物件中直接拷貝得到,而不用每次在建立新物件的時候,都重複執行這些耗時的操作。

通過個人資訊類(information)建立兩個例項物件(zs、lf)。

抽象原型類如下:

class

information

:"""個人資訊"""

def__init__

(self)

: self.name =

none

self.age =

none

self.height =

none

self.hobbies =

list()

defrun

(self)

:"""自我介紹方法"""

print

("我叫{}: 年齡:{} 身高:{} 愛好: {}"

.format

(self.name, self.age, self.height, self.hobbies)

)

具體原型類如下:

class

prototype

:def

__init__

(self, obj)

: self.copy_object = obj(

)def

clone

(self,

**attr)

:'''轉殖物件'''

obj = copy.deepcopy(self.copy_object)

# 深轉殖

obj.__dict__.update(attr)

return obj

客戶類

if __name__ ==

'__main__'

: people = prototype(information)

# 例項化乙個具體原型

zs = people.clone(name=

'張山'

, age=

"30"

, height=

'170cm'

, hobbies=

['**'

,'讀書'])

zs.run(

) lf = people.clone(name=

'李飛'

, age=

"20"

, height=

'190cm'

, hobbies=

['籃球'

,'羽毛球'])

lf.run(

)

輸出結果:

我叫張山: 年齡:30 身高:170cm 愛好:

['**'

,'讀書'

]我叫李飛: 年齡:20 身高:190cm 愛好:

['籃球'

,'羽毛球'

]

也可以換一種寫法,寫成如下形式:

import copy

class

information

:"""個人資訊"""

def__init__

(self)

: self.name =

none

self.age =

none

self.height =

none

self.hobbies =

list()

defrun

(self)

:"""自我介紹方法"""

print

("我叫{}: 年齡:{} 身高:{} 愛好: {}"

.format

(self.name, self.age, self.height, self.hobbies)

)if __name__ ==

'__main__'

: zs = copy.deepcopy(information())

zs.name =

'張三'

zs.age =

"30"

zs.height =

'170cm'

zs.hobbies =

['**'

,'讀書'

] zs.run(

) lf = copy.copy(information())

lf.name =

'李飛'

lf.age =

'20'

lf.height =

'190cm'

lf.hobbies =

['籃球'

,'羽毛球'

] lf.run(

)

上面例子中使用的是深轉殖(深拷貝)。其實還有淺轉殖(淺拷貝)。

淺轉殖(淺拷貝)

深轉殖(深拷貝)

淺轉殖可能出現以下問題。舉例

>>

>

import copy

>>

> a =[1

,"2",[

'a',

none]]

>>

> b = copy.copy(a)

# 淺轉殖

>>

> b[1

,'2',[

'a',

none]]

>>

> c = copy.deepcopy(a)

# 深轉殖

>>

> c[1

,'2',[

'a',

none

]]

b淺轉殖a,c深轉殖a。

如果a修改了列表中巢狀的子列表中的內容,則b也會跟著變動,而深轉殖的c卻不會發生變化。

>>

> a[2]

1)# >>

> a[1

,'2',[

'a',

none,1

]]>>

> b # 可以看出,b也被修改了[1

,'2',[

'a',

none,1

]]>>

> c[1

,'2',[

'a',

none

]]

這是因為b只是轉殖了a[2]指向的記憶體位址,而**a[2]是乙個列表,列表屬於可變型別**,因此,當a[2]發生變化時,b也跟著變動。這就是淺轉殖的***;而c直接完全轉殖了a中的值,並不會因為a發生變化而變化。

所以,一般建議使用深轉殖。

大話設計模式 原型模式

學無止境,精益求精 十年河東,十年河西,莫欺少年窮 學歷代表你的過去,能力代表你的現在,學習代表你的將來 上篇部落格介紹了c 深淺複製,其實原型模式講的主要就是物件的深淺複製 參考 c 深淺複製 memberwiseclone ok,言歸正傳 原型模式的概念 用原型例項指定建立物件的種類,並且通過拷...

《大話設計模式 原型模式》筆記

1 原型模式 prototype 用原型例項指定建立物件的種類,並通過拷貝這些原型建立新的物件。2 原型模式結構圖 3 簡單 實現 3.1 繼承cloneable介面 public class concrereprototype implements cloneable public string ...

大話設計模式 原型模式 9

using system using system.collections.generic using system.linq using system.text namespace prototypefactory public prototype string id public abstrac...