利用動態語言特性實現工廠模式

工廠模式有多種實現,比較簡單的一種實現稱之為簡單工廠模式(Simple Factory Pattern)。簡單工廠模式又稱為靜態工廠方法(Static Factory Method)模式,它屬於類創建型模式。在簡單工廠模式中,可以根據參數的不同返回不同類的實例,被創建的實例通常都具有共同的父類。

例如,下面這段程序就是C++語言實實現的一個簡單工廠模式:

class Shapenclass Circle: public Shapenclass Square: public ShapennShape* Shape::factory(const string &type)n{n if (type == "Circle")n {return new Circle;}n if (type == "Square")n {return new Square;}n}n

在Python中,我們也可以參考C++的實現,在工廠函數中,通過參數的名稱來返回不同的對象。但是,這裡的工廠函數存在一個擴展性問題。當我們增加了新形狀以後,需要修改factory函數,增加一個if語句來返回新的對象。在Python語言中,我們完全不需要這麼做,因為我們有更好的實現方式。

在Python語言中,locals函數與globals函數是兩個特殊的函數,前者返回局部命名空間,後者返回全局命名空間。換句話說,我們在Python模塊頂層定義的變數、函數和類,都屬於全局命名空間。globals函數返回的是全局命名空間,因此,我們可以通過globals函數獲取全局命名空間中的變數、函數和類。例如,在下面這個例子中,我們首先定義了一個全局變數A,然後我們在f函數中,通過globals函數獲得了全局命名空間,通過鍵A獲取了我們之前定義的全局變數。獲取全局變數以後,我們修改全局變數A的值為2。在下面這段程序中,最後會輸出2 。

A = 1nndef f():n globals()[A] = 2nnf()nprint(A)n

既然我們可以通過變數的名稱,從globals函數的返回的字典中,得到全局變數。那麼,我們也可以通過類的名稱,從globals函數返回的字典中獲得類對象。獲得類對象以後,執行了類調用就創建了一個對象。如下所示:

class Shape(object):passnclass Circle(Shape):passnclass Square(Shape):passnnfor name in ["Circle", "Square"]:n cls = globals()[name]n obj = cls()n

在這段程序中,我們將形狀的名稱作為參數,然後從globals函數返回的字典中獲取類對象,接著執行類調用得到一個形狀。我們利用Python語言的動態語言特性,以一種非常簡單的方式實現了C++語言中的簡單工廠模式,並且保證了程序的擴展性。

推薦閱讀:

TAG:Python | 设计模式 |