原型(prototype
)模式主要用於建立物件的轉殖,通常其最簡單的形式就是採用自定
clone()函式並
傳入物件引數以返回此物件的乙個副本,這在
python
實作上可使用內定
copy.cop
y()或
copy.deepcopy()
函式來達到此目的。
當已有乙個物件但對此物件的某些部分會被變更卻又想保持原有物件不變之部份時,此時便可利用此物件的副本來進行改造,這就可採用原型模式來協助開發工作,因在這樣的案例中再重新建立原有物件是沒有意義且毫無效率可言的,如在實際應用中物件是從資料庫中獲取的,當日後有需求須再次從資料庫中引用已獲取的物件,若通過建立同乙個物件來作訪查資料,則會造成重複程式碼及記憶體效能不佳等問題,在這種場景下使用原型模式是最佳的解決方案。
示例:
from collections import ordereddict
import copy
class book:
"""使用rest可變引數並使用self.__dict__.update(rest)將rest內容新增到內部既定dict中。
"""def __init__(self, name, authors, price, **rest):
'''rest:含出版商、長度、 標籤、出版日期等字串資訊'''
self.name = name
self.authors = authors
self.price = price
self.__dict__.update(rest)
def __str__(self):
"""由於既定dict內容並不遵循任何特定的順序,故此處使用ordereddict來強制元素使之變成有序,以避免每次程式執行產生不同的輸出。
"""mylist =
ordered =ordereddict(sorted(self.__dict__.items()))
for i in ordered.keys():
if i == 'price':
return''.join(mylist)
class prototype:
"""此類核心是自定clone()方法,該方法使用內定copy.deepcopy()函式來完成轉殖工作。另在此類中還包含register()和unregister()方法用於在dict中註冊及釋放被轉殖的物件。
"""def __init__(self):
self.objects = dict()
def register(self, identifier, obj):
self.objects[identifier] = obj
def unregister(self, identifier):
del self.objects[identifier]
def clone(self, identifier, **attr):
"""此方法採用與book類中的__str__()相同技巧,即使用可變引數來傳遞需要變更的屬性值。
identifier:版本號
attr: 新新增的屬性
"""found = self.objects.get(identifier)
if not found:
raise valueerror('incorrect object identifier: {}'.format(identifier))
obj = copy.deepcopy(found)
obj.__dict__.update(attr)
return obj
def main():
"""此處實踐轉殖書的第乙個版本來建立第二個新版本,但除傳遞既有引數中要被修改的屬性值外,也可以再傳遞額外的引數,如edition就是乙個新引數。
"""b1 = book('the c programming language', ('brian w. kernighan', 'dennis m.ritchie'), price=118, publisher='prentice hall', length=228, publication_date='1978-02-22',tags=('c', 'programming', 'algorithms', 'data structures'))
prototype = prototype()
cid = 'k&r-first' #此只是定義有意義的變數名
prototype.register(cid, b1)
b2 = prototype.clone(cid,name='the c programming language(ansi)', price=48.99, length=274, publication_date='1988-04-01',edition=2)
for i in (b1, b2):
print(i)
print("id b1 : {} != id b2 : {}".format(id(b1), id(b2)))
if __name__ == '__main__':
main()
輸出:
authors: ('brian w. kernighan', 'dennis m.ritchie')
length: 228
name: the c programming language
price: 118$
publication_date: 1978-02-22
publisher: prentice hall
tags: ('c', 'programming', 'algorithms', 'data structures')
authors: ('brian w. kernighan', 'dennis m.ritchie')
edition: 2
length: 274
name: the c programming language(ansi)
price: 48.99$
publication_date: 1988-04-01
publisher: prentice hall
tags: ('c', 'programming', 'algorithms', 'data structures')
id b1 : 2255182842680 != id b2 : 2255184004488
總結:
在python
中其轉殖方式有深副本與淺副本二種型式:
建立型模式 原型模式
使用原型例項指定建立物件的種類,並且通過轉殖這些原型建立新的物件 原理是將乙個原型物件傳給要發動建立的物件,該物件通過請求原型物件轉殖自己來建立過程 轉殖方法 public prototype clone jdk中為我們提供了轉殖的方法clone 從object繼承下來,乙個物件要實現轉殖,需要實現...
原型模式 建立型模式
文章首發個人部落格 如果我們有乙個類 sheep 它裡面有兩個屬性,名稱 name 年齡 age 現在我們有乙個它的例項 s1 我們需要按照這個例項的屬性再去建立兩個物件。1 sheep data public class sheep 2 main public class main 原型模式 用原...
建立型模式 原型模式 prototype
用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。main.cc include include software computer.h design pattern prototype for example,the company to employees with compute...