4.設計模式之二:原型模式【建立型模式】

在有些系統中,存在大量相同或類似對象的建立問題,若是用傳統的構造函數來建立對象,會比較複雜且耗時耗資源,用原型模式生成對象就很高效,就像孫悟空拔下猴毛輕輕一吹就變出不少孫悟空同樣簡單。python

定義與特色

原型(Prototype)模式的定義以下:用一個已經建立的實例做爲原型,經過複製該原型對象來建立一個和原型相同或類似的新對象。函數

在這裏,原型實例指定了要建立的對象的種類。用這種方式建立對象很是高效,根本無須知道對象建立的細節。spa

例如,Windows 操做系統的安裝一般較耗時,若是複製就快了不少。在生活中複製的例子很是多,這裏不一一列舉了。操作系統

結構與實現

模式的結構

原型模式包含如下主要角色。3d

  1. 抽象原型類:規定了具體原型對象必須實現的接口。
  2. 具體原型類:實現抽象原型類的 clone() 方法,它是可被複制的對象。
  3. 訪問類:使用具體原型類中的 clone() 方法來複制新的對象。

模式的實現

from copy import copy, deepcopy
class Prototype(object):
    '''抽象原型類'''
    def clone(self):
        # 淺拷貝
        pass

    def deep_clone(self):
        # 深拷貝
        pass

class Realizetype(Prototype):
    '''具體原型類'''
    cls_s = [[1, 2, 3], 4, 5, 6]
    def __init__(self):
        self.s = [[1, 2, 3], 4, 5, 6]
        print("具體原型類實例化成功!")

    def clone(self):
        print("具體原型類潛複製成功!")
        return copy(self)

    def deep_clone(self):
        print("具體原型類深複製成功!")
        return deepcopy(self)

if __name__ == '__main__':
    rt = Realizetype()
    copy_rt = rt.clone()
    deep_copy_rt = rt.deep_clone()
    
    rt.s[0][1] = 10
    rt.cls_s[0][1] = 10
    print(rt.s, copy_rt.s, deep_copy_rt.s)
    print(rt.cls_s, copy_rt.cls_s, deep_copy_rt.cls_s)
具體原型類實例化成功!
具體原型類潛複製成功!
具體原型類深複製成功!
[[1, 10, 3], 4, 5, 6] [[1, 10, 3], 4, 5, 6] [[1, 2, 3], 4, 5, 6]
[[1, 10, 3], 4, 5, 6] [[1, 10, 3], 4, 5, 6] [[1, 10, 3], 4, 5, 6]

從結果中能夠發現,潛複製中可變元素中嵌套有可變元素,一旦嵌套中的可變元素髮生變化,潛複製的值也會發生變化,即原來的[1,2, 3]變成了[1, 10, 3]。code

可是類屬性卻會跟着變化,由於類屬性只屬於類,不屬於實例。注意這種差別只有在可變元素中發生。對象

【例1】用原型模式生成「三好學生」獎狀blog

分析:同一學校的「三好學生」獎狀除了獲獎人姓名不一樣,其餘都相同,屬於類似對象的複製,一樣能夠用原型模式建立,而後再作簡單修改就能夠了。圖 4 所示是三好學生獎狀生成器的結構圖。接口

from copy import copy
class Prototype(object):
    def clone(self):
        pass

class Citation(Prototype):
    def __init__(self, name, info, college):
        self.__name = name
        self.__info = info
        self.__college = college
        print("獎狀建立成功!")

    def clone(self):
        return copy(self)

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name

    @property
    def info(self):
        return self.__info

    @info.setter
    def info(self, info):
        self.__info = info

    @property
    def college(self):
        return self.__college

    @college.setter
    def college(self, college):
        self.__college = college

    def show(self):
        print(self.__name, self.__info, self.__college)

if __name__ == '__main__':
    st1 = Citation("zhang", "三好學生", "南京大學")
    st2 = st1.clone()
    st2.name = "wang"
    st2.college = "北京大學"
    st1.show()
    st2.show()
獎狀建立成功!
zhang 三好學生 南京大學
wang 三好學生 北京大學

應用場景

原型模式一般適用於如下場景。資源

  • 對象之間相同或類似,即只是個別的幾個屬性不一樣的時候。
  • 對象的建立過程比較麻煩,但複製比較簡單的時候。

原型模式的擴展

原型模式可擴展爲帶原型管理器的原型模式,它在原型模式的基礎上增長了一個原型管理器 PrototypeManager 類。該類用 HashMap 保存多個複製的原型,Client 類能夠經過管理器的 get(String id) 方法從中獲取複製的原型。其結構圖如圖所示。

【例2】用帶原型管理器的原型模式來生成包含「圓」和「正方形」等圖形的原型,並計算其面積。

分析:本實例中因爲存在不一樣的圖形類,例如,「圓」和「正方形」,它們計算面積的方法不同,因此須要用一個原型管理器來管理它們,圖所示是其結構圖。

相關文章
相關標籤/搜索