以前聽過這樣一句話:「程式設計師的最高境界就是ctrl+c、ctrl+v」,我們先不論這句話的對錯,就論這個過程,這個過程我們都知道無非就是複製乙個物件,然後將其不斷地貼上。這樣的過程我們可以將其稱之為「轉殖」。再如我們應聘的時候列印了那麼多的簡歷。
轉殖我們都清楚,就是用乙個物體複製若干個一模一樣物體。同樣,在物件導向系統中,我們同樣可以利用轉殖技術來轉殖出若干個一模一樣的物件。在應用程式中,有些物件比較複雜,其建立過程過於複雜,而且我們又需要頻繁的利用該物件,如果這個時候我們按照常規思維new該物件,那麼務必會帶來非常多的麻煩,這個時候我們就希望可以利用乙個已有的物件來不斷對他進行複製就好了,這就是程式設計中的「轉殖」。這裡原型模式就可以滿足我們的「轉殖」,在原型模式中我們可以利用過乙個原型物件來指明我們所要建立物件的型別,然後通過複製這個物件的方法來獲得與該物件一模一樣的物件例項。這就是原型模式的設計目的。
模式定義
通過前面的簡單介紹我們就可以基本確定原型模式的定義了。所謂原型模式就是用原型例項指定建立物件的種類,並且通過複製這些原型建立新的物件。
在原型模式中,所發動建立的物件通過請求原型物件來拷貝原型物件自己來實現建立過程,當然所發動建立的物件需要知道原型物件的型別。這裡也就是說所發動建立的物件只需要知道原型物件的型別就可以獲得更多的原型例項物件,至於這些原型物件時如何建立的根本不需要關心。
講到原型模式了,我們就不得不區分兩個概念:深拷貝、淺拷貝。
淺拷貝:使用乙個已知例項對新建立例項的成員變數逐個賦值,這個方式被稱為淺拷貝。
深拷貝:當乙個類的拷貝構造方法,不僅要複製物件的所有非引用成員變數值,還要為引用型別的成員變數建立新的例項,並且初始化為形式引數例項值。
對於深淺拷貝以前的文章介紹過
角色
原型模式主要包含如下三個角色:
prototype:抽象原型類。宣告轉殖自身的介面。
concreteprototype:具體原型類。實現轉殖的具體操作。
client:客戶類。讓乙個原型轉殖自身,從而獲得乙個新的物件。
1、如果建立新的物件比較複雜時,可以利用原型模式簡化物件的建立過程,同時也能夠提高效率。
2、可以使用深轉殖保持物件的狀態。
3、原型模式提供了簡化的建立結構。
1、在實現深轉殖的時候可能需要比較複雜的**。
2、需要為每乙個類配備乙個轉殖方法,而且這個轉殖方法需要對類的功能進行通盤考慮,這對全新的類來說不是很難,但對已有的類進行改造時,不一定是件容易的事,必須修改其源**,違背了「開閉原則」。
對於以上缺點python中有專門處理深轉殖的方法deepcopy
1、如果建立新物件成本較大,我們可以利用已有的物件進行複製來獲得。
2、如果系統要儲存物件的狀態,而物件的狀態變化很小,或者物件本身佔記憶體不大的時候,也可以使用原型模式配合備忘錄模式來應用。相反,如果物件的狀態變化很大,或者物件占用的記憶體很大,那麼採用狀態模式會比原型模式更好。
3、需要避免使用分層次的工廠類來建立分層次的物件,並且類的例項物件只有乙個或很少的幾個組合狀態,通過複製原型物件得到新例項可能比使用建構函式建立乙個新例項更加方便。
**實現
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""大話設計模式
設計模式——原型模式
原型模式(prototype pattern):用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件
原型模式是用場景:需要大量的基於某個基礎原型進行微量修改而得到新原型時使用
"""from copy import copy, deepcopy
# 原型抽象類
class prototype(object):
def clone(self):
pass
def deep_clone(self):
pass
# 工作經歷類
class workexperience(object):
def __init__(self):
self.timearea = ''
self.company = ''
def set_workexperience(self,timearea, company):
self.timearea = timearea
self.company = company
# 簡歷類
class resume(prototype):
def __init__(self,name):
self.name = name
self.workexperience = workexperience()
def set_personinfo(self,***,age):
self.*** = ***
self.age = age
pass
def set_workexperience(self,timearea, company):
self.workexperience.set_workexperience(timearea, company)
def display(self):
print self.name
print self.***, self.age
print '工作經歷',self.workexperience.timearea, self.workexperience.company
def clone(self):
return copy(self)
def deep_clone(self):
return deepcopy(self)
if __name__ == '__main__':
obj1 = resume('andy')
obj2 = obj1.clone() # 淺拷貝物件
obj3 = obj1.deep_clone() # 深拷貝物件
obj1.set_personinfo('男',28)
obj1.set_workexperience('2010-2015','aa')
obj2.set_personinfo('男',27)
obj2.set_workexperience('2011-2017','aa') # 修改淺拷貝的物件工作經歷
obj3.set_personinfo('男',29)
obj3.set_workexperience('2016-2017','aa') # 修改深拷貝的物件的工作經歷
設計模式 原型模式
1.首先分析原型模式的由來 一般來說,建立乙個物件可以由以下方法 知道物件的具體型別,直接用new生成。不知道型號,知道相應的需求,可以使用工廠方法模式。根據乙個已有的物件來複製為乙個新的物件,可以使用原型模式。2.原型模式可以簡單理解為拷貝原型物件得到新的物件。想象乙個配鑰匙的小店,給店主乙個原有...
設計模式 原型模式
魔術師手拿一張百元大鈔,瞬間又變出兩張。也像配鑰匙一樣,拿一把鑰匙,老師傅就能做出另乙個一模一樣的。像這種複製我們並不陌生,類似於我們設計中的原型模式 本文將從以下幾點 原型模式 概述 結構圖 淺複製深複製 總結 用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。允許乙個物件再建立另外...
設計模式 原型模式
原型模式 用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。1 假設我們現有乙個物件,但是它的型別需要執行期確定,我們不知道它的動態型別是什麼,現在我們想建立它的副本。顯然通過建構函式建立是很麻煩的,這時候我們可以使用原型模式中的clone函式直接得到該物件的副本。2 有些時候我們想要...