1. 程式人生 > >pyhon面向對象設計之抽象工廠模式

pyhon面向對象設計之抽象工廠模式

python 面向對象 抽象工廠模式

簡介

抽象工廠設計模式屬於創建型設計模式的一種,創建型設計模式更關註對象是如何被創建出來的。通常我們會調用對象的構造函數來創建對象實例,比如通過向類名稱傳遞相關參數來創建。但是,有時候我們會需要更加靈活的對象創建方式,這時創建型的設計模式就會大有用處了。今天我們主要關註創建型的設計模式中的抽象工廠設計模式。抽象工廠設計模式主要用於對於某一個系統而言,根據配置文件的不同或者系統平臺(windows/mac/linux)的不同有多種不同的實現方式的時候。
比如:在一個GUI系統裏,我們可能有一個抽象的窗口小部件工廠,而這個工廠有三個具體實現子類工廠:MacWidgetFactory, xfceWidgetFactory和WindowsWidgetFactory, 所有的這些子類工廠中都提供了創建相同窗口小部件的方法,比如類似於make_button(), make_spinbox()等等,這些方法則根據不同的平臺提供了不同的具體實現。這樣,我們就可以通過向同一個函數create_dialog()傳遞不同的工廠實例,從而產生出平臺相關的不同的窗口的外觀樣式,比如:windows樣式的、mac樣式的。

一個典型的抽象工廠
為了演示抽象工廠設計模式,我們來看一個產生簡單圖表的程序。在這個程序裏我們設計了兩個不同的工廠:一個產生純文本方式的圖表,二另外一個輸出可縮放的矢量圖形式。輸出圖形如圖1所示。
技術分享圖片
圖1 程序輸出結果
首先看一下main()函數:
技術分享圖片
textFilename與svgFilename是兩個文件,用來存儲diagram的相關信息,我們調用了相同的create_diagram函數,並傳遞了不同的工廠實例,從而返回了不同的結果。依據不同的配置文件返回了不同的處理結果,這是典型的抽象工廠模式。我們來更進一步查看create_diagram是如何定義的。
技術分享圖片
這個函數接受一個factory作為它唯一的參數,並根據factory的不同創建不同的圖表。這個函數並不知道或者根本不關心它所接收的到底是哪一類工廠,只要它支持圖表工廠的接口即可。下面我們來看下這兩個不同的工廠是如何定義的。
技術分享圖片
上述是純文本格式圖表工廠的定義,實際上它也是基類工廠,svgDiagramFactory是派生自這個工廠的。盡管這種設計模式采用了“抽象”這個詞語,在實際實現過程中,比較常見的做法是將某個類既作為基類提供相應的接口,同時它本身又是一個具體的子類。本例中的DiagramFactory即是這樣使用的。
技術分享圖片
上面是svg圖表工廠的幾行代碼,與純文本格式圖表工廠的make_diagram()方法唯一的不同在於純文本格式圖表工廠的make_diagram()方法返回了一個Diagram對象。而svgDiagramFactory的make_diagram()方法返回了一個SvgDiagram對象。make_rectange和make_text()方法與之類似。
純文本格式的圖表工廠用一個由一系列單字符列表組成的列表來存儲相應的信息,這些單字符從圖1中就可以看出來包括了空格、+、-、|、%等等。程序會在初始化的時候,將由width和height參數指定的寬和高覆蓋的區域,初始化成一系列空格覆蓋的區域。當調用add方法的時候,就會將rectangle及text指定的位置替換成上述的單字符及本身包含的字符內容。
技術分享圖片
這個是Text類的所有代碼,對於純文本格式的圖表工廠最後一個fontsize參數可以忽略。可以看到,Text類中保存了一個rows的列表,該列表的每個元素也是一個列表,其元素為text中的每個字符。
技術分享圖片
這是Diagram的add方法,它接收一個component(即Text或者Rectangle)為參數,而後遍歷component中保存的rows參數,並將diagram中的相應位置替換成相應的字符串。
技術分享圖片
這個是SvgText的類代碼,以及它所以來的兩個常量的定義。使用 **locals()這種定義方法,可以簡化代碼,而無需寫成如下的格式SVG_TEXT.format(x=x,y=y,text=text,fontsize=fontsize)。而從Python3.2開始,可以使用SVG_TEXT.format_map(locals())代替,因為str.format_map()幫助我們進行了參量的解壓縮。對於SvgDiagram類而言,每個實例裏存儲著一個字符串列表self.digram,列表裏的每個元素都是一段html代碼。這樣就使得添加新的SvgRectangle和SvgText等類型的組件非常方便。
上述代碼雖然以抽象工廠模式的代碼實現了相應的功能,但代碼不夠簡潔,不夠pythonic,所以第二篇文章,我們希望能夠通過相應的改進,能夠讓代碼更加簡潔並且pythonic化,敬請期待!
好了,這個是我們面向對象程序設計裏的抽象工廠方法的第一篇文章,喜歡的話給個贊吧,謝謝!

pyhon面向對象設計之抽象工廠模式