創建類設計模式(5種)——原型模式

創建類設計模式(5種)——原型模式

一、圖層

大家如果用過類似於Photoshop的平面設計軟件,一定都知道圖層的概念。圖層概念的提出,使得設計、圖形修改等操作更加便利。設計師既可以修改和繪製當前圖像對象,又可以保留其它圖像對象,邏輯清晰,且可以及時得到反饋。本節內容,將以圖層爲主角,介紹原型模式。
首先,設計一個圖層對象。

 

class simpleLayer:
    background=[0,0,0,0]
    content="blank"
    def getContent(self):
        return self.content
    def getBackgroud(self):
        return self.background
    def paint(self,painting):
        self.content=painting
    def setParent(self,p):
        self.background[3]=p
    def fillBackground(self,back):
        self.background=back

 

在實際的實現中,圖層實現會很複雜,這裏僅介紹相關的設計模式,做了比較大的抽象,用background表示背景的RGBA,簡單用content表示內容,除了直接繪畫,還可以設置透明度。
新建圖層,填充藍底並畫一隻狗,可以簡單表示如下:

if  __name__=="__main__":
    dog_layer=simpleLayer()
    dog_layer.paint("Dog")
    dog_layer.fillBackground([0,0,255,0])
    print "Background:",dog_layer.getBackgroud()
    print "Painting:",dog_layer.getContent()

打印如下:
Background: [0, 0, 255, 0]
Painting: Dog


接下來,如果需要再生成一個同樣的圖層,再填充同樣的顏色,再畫一隻同樣狗,該如何做呢?還是按照新建圖層、填充背景、畫的順序麼?或許你已經發現了,這裏可以用複製的方法來實現,而複製(clone)這個動作,就是原型模式的精髓了。
按照此思路,在圖層類中新加入兩個方法:clone和deep_clone

 

from copy import copy, deepcopy
class simpleLayer:
    background=[0,0,0,0]
    content="blank"
    def getContent(self):
        return self.content
    def getBackgroud(self):
        return self.background
    def paint(self,painting):
        self.content=painting
    def setParent(self,p):
        self.background[3]=p
    def fillBackground(self,back):
        self.background=back
    def clone(self):
        return copy(self)
    def deep_clone(self):
        return deepcopy(self)
if  __name__=="__main__":
    dog_layer=simpleLayer()
    dog_layer.paint("Dog")
    dog_layer.fillBackground([0,0,255,0])
    print "Background:",dog_layer.getBackgroud()
    print "Painting:",dog_layer.getContent()
    another_dog_layer=dog_layer.clone()
    print "Background:", another_dog_layer.getBackgroud()
    print "Painting:", another_dog_layer.getContent()

 

打印結果如下:
Background: [0, 0, 255, 0]
Painting: Dog
Background: [0, 0, 255, 0]
Painting: Dog
clone和deep_clone有什麼區別呢?大多數編程語言中,都會涉及到深拷貝和淺拷貝的問題,一般來說,淺拷貝會拷貝對象內容及其內容的引用或者子對象的引用,但不會拷貝引用的內容和子對象本身;而深拷貝不僅拷貝了對象和內容的引用,也會拷貝引用的內容。所以,一般深拷貝比淺拷貝複製得更加完全,但也更佔資源(包括時間和空間資源)。舉個例子,下面的場景,可以說明深拷貝和淺拷貝的區別。

if  __name__=="__main__":
    dog_layer=simpleLayer()
    dog_layer.paint("Dog")
    dog_layer.fillBackground([0,0,255,0])
    print "Original Background:",dog_layer.getBackgroud()
    print "Original Painting:",dog_layer.getContent()
    another_dog_layer=dog_layer.clone()
    another_dog_layer.setParent(128)
    another_dog_layer.paint("Puppy")
    print "Original Background:", dog_layer.getBackgroud()
    print "Original Painting:", dog_layer.getContent()
    print "Copy Background:", another_dog_layer.getBackgroud()
    print "Copy Painting:", another_dog_layer.getContent()

複製代碼

打印如下:
Original Background: [0, 0, 255, 0]
Original Painting: Dog
Original Background: [0, 0, 255, 128]
Original Painting: Dog
Copy Background: [0, 0, 255, 128]
Copy Painting: Puppy


淺拷貝後,直接對拷貝後引用(這裏的數組)進行操作,原始對象中該引用的內容也會變動。如果將another_dog_layer=dog_layer.clone()換成another_dog_layer=dog_layer.deep_clone(),即把淺拷貝換成深拷貝,其如果如下:


Original Background: [0, 0, 255, 0]
Original Painting: Dog
Original Background: [0, 0, 255, 0]
Original Painting: Dog
Copy Background: [0, 0, 255, 128]
Copy Painting: Puppy


深拷貝後,其對象內的引用內容也被進行了複製。

 

二、原型模式

原型模式定義如下:用原型實例指定創建對象的種類,並且通過複製這些原型創建新的對象。
需要注意一點的是,進行clone操作後,新對象的構造函數沒有被二次執行,新對象的內容是從內存裏直接拷貝的。


f1.png

 

三、原型模式的優點和使用場景

優點:

1、性能極佳,直接拷貝比在內存裏直接新建實例節省不少的資源;
2、簡化對象創建,同時避免了構造函數的約束,不受構造函數的限制直接複製對象,是優點,也有隱患,這一點還是需要多留意一些。

使用場景:

1、對象在修改過後,需要複製多份的場景。如本例和其它一些涉及到複製、粘貼的場景;
2、需要優化資源的情況。如,需要在內存中創建非常多的實例,可以通過原型模式來減少資源消耗。此時,原型模式與工廠模式配合起來,不管在邏輯上還是結構上,都會達到不錯的效果;
3、某些重複性的複雜工作不需要多次進行。如對於一個設備的訪問權限,多個對象不用各申請一遍權限,由一個設備申請後,通過原型模式將權限交給可信賴的對象,既可以提升效率,又可以節約資源。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章