Python 設計模式—— Simple Factory 模式
發表于:2007-07-04來源:作者:點擊數:
標簽:
一、創建型模式 創建型模式(Creational Pattern)對類的實例化過程進行了抽象,能夠使軟件模塊做到與對象創建和組織的無關性。為了使體系結構更加清晰,一些軟件在設計上要求當創建類的具體實例時,能夠根據具體的語境來動態地決定怎樣創建對象,創建哪些對
一、創建型模式
創建型模式(Creational Pattern)對類的實例化過程進行了抽象,能夠使軟件模塊做到與對象創建和組織的無關性。為了使體系結構更加清晰,一些軟件在設計上要求當創建類的具體實例時,能夠根據具體的語境來動態地決定怎樣創建對象,創建哪些對象,以及怎樣組織和表示這些對象,而創建型模式所要描述的就是該如何來解決這些問題。
按照生成目標的不同,創建型模式可以分為類的創建型模式和對象的創建型模式兩種:
類的創建型模式
類的創建型模式通過使用繼承關系,將類的創建交由具體的子類來完成,這樣就向外界隱藏了如何得到具體類的實現細節,以及這些類的實例是如何被創建和組織在一起的。
對象的創建型模式
對象的創建型模式通過把對象的創建委托給另一個對象來完成,可以根據語境動態地決定生成哪些具體類的實例,同時還可以向外界隱藏這些實例是如何被創建以及如何被組織在一起的細節。
所有的創建型模式都有兩個永恒的主旋律:第一,它們都將系統使用哪些具體類的信息封裝起來;第二,它們隱藏了這些類的實例是如何被創建和組織的。外界對于這些對象只知道它們共同的接口,而不清楚其具體的實現細節。正因如此,創建型模式在創建什么(what),由誰(who)來創建,以及何時(when)創建這些方面,都為軟件設計者提供了盡可能大的靈活性。
具體到Python來說,假設有這樣一個類:
class Person:
def __init__(self, name):
self.name = name
要創建該類的一個實例,則應該執行下面的語句:
p = Person("Gary")
但如果創建對象時完成的工作非常復雜,需要一段很長的代碼,你就不能簡單地將其全部寫入__init__方法中,因為這會違背
面向對象思想的兩個基本原則:封裝(encapsulation)和委派(delegation)。假如執意要做樣做,結果只會使你的代碼變成一段行為固定的硬編碼(hard coding),而整個軟件的結構都極有可能變得非常糟糕,因為其它某個模塊也許就正依賴于你所創建的這個實例,這樣就在無形之間增加了模塊之間的耦合度。
將Python對象的創建過程封裝到某個類中來單獨完成,可以使你的程序變得更加靈活和通用。實踐證明,使用下面的六種創建型模式可以更好地改善對象的創建過程:
Simple Factory模式
專門定義一個類來負責創建其它類的實例,被創建的實例通常都具有共同的父類。
Factory Method模式
將對象的創建交由父類中定義的一個標準方法來完成,而不是其構造函數,究竟應該創建何種對象由具體的子類負責決定。
Abstract Factory模式
提供一個共同的接口來創建相互關聯的多個對象。
Singleton模式
保證系統只會產生該類的一個實例,同時還負責向外界提供訪問該實例的標準方法。
Builder模式
將復雜對象的創建同它們的具體表現形式(representation)區別開來,這樣可以根據需要得到具有不同表現形式的對象。
Prototype模式
利用一個能對自身進行復制的類,使得對象的動態創建變得更加容易。
二、模式引入
簡單工廠(Simple Factory)模式又稱為靜態工廠方法(Static Factory Method)模式,屬于類的創建型模式。這種模式根據外界給定的信息,由"工廠"對象"制造"出某些可能"產品"類中的一個實例,工廠對象能夠處理的所有類通常都繼承于同一個父類,并且對外界提供基本相同的接口,只不過在具體實現時會有所差別罷了。
假設我們要
開發一個繪圖程序,用來繪制簡單的幾何圖形,這個軟件應該能夠處理下面的幾種幾何對象:
圓形(Circle)
矩形(Rectangle)
菱形(Diamond)
除了各自特有的屬性和方法之外,所有的幾何圖形幾乎都可以抽象出繪制(draw)和擦除(erase)兩個公共方法,因而可以為它們定義一個共同的接口Shape。雖然Python語言本身并不支持接口,但為了更好地闡明設計模式的思想,有時我們還是會借用一下
UML中的接口這一概念。這樣一來,各個類之間的關系就將如圖1所示:
圖1 Shape接口定義了所有幾何圖形都必須實現的公共方法: draw()和erase(),實現該接口的Python代碼如下所示,Python中沒有接口的概念,因此在具體實現時可以使用類來替代。
代碼清單1:shape.py
class Shape:
# 繪制圖形
def draw(self):
pass
# 擦除圖形
def erase(self):
pass
Circle類是Shape的一種具體形式,它實現了Shape接口定義的所有方法,此外還添加了一個屬性__radius,用來表示圓的半徑。以下是實現Circle類的代碼:
代碼清單2:circle.py
class Circle (Shape):
def __init__(self, radius = 0):
self.__radius = radius
# 繪制圓形
def draw(self):
print "Draw Circle"
# 擦除圓形
def erase(self):
print "Erase Circle"
# 半徑的取值方法
def getRadius(self):
return self.__radius
# 半徑的賦值方法
def setRadius(self, radius):
self.__radius = radius
Rectangle類也是Shape的一種具體形式,它實現了Shape接口定義的所有方法,并添加了__width和__height兩個屬性,分別表示矩形的寬度和高度。以下是實現Rectangle類的代碼:
代碼清單3:rectangle.py
class Rectangle (Shape):
def __init__(self, width = 0, height = 0):
self.__width = width
self.__height = height
# 繪制矩形
def draw(self):
print "Draw Rectangle"
# 擦除矩形
def erase(self):
print "Erase Rectangle"
# 寬度的取值方法
def getWidth(self):
return self.__width
# 寬度的賦值方法
def setWidth(self, width):
self.__width = width
# 高度的取值方法
def getHeight(self):
return self.__height
# 高度的賦值方法
def setHeight(self, height):
self.__height = height
同樣,Diamond類也是Shape的一種具體形式,它實現了Shape接口中定義的所有方法,并且添加了__width和__height兩個屬性,分別表示菱形的寬度和高度。以下是實現Diamond類的代碼:
代碼清單4:diamond.py
class Diamond (Shape):
def __init__(self, width = 0, height = 0):
self.__width = width
self.__height = height
# 繪制菱形
def draw(self):
print "Draw Diamond"
# 擦除菱形
def erase(self):
print "Erase Diamond"
# 寬度的取值方法
def getWidth(self):
return self.__width
# 寬度的賦值方法
def setWidth(self, width):
self.__width = width
# 高度的取值方法
def getHeight(self):
return self.__height
# 高度的賦值方法
def setHeight(self, height):
self.__height = height
所有幾何圖形類都定義好后,下面要做的就是提供一個"工廠"類ShapeFactory,來創建各種幾何圖形的具體實例。ShapeFactory類的作用就是根據外界的要求,創建出不同的幾何圖形對象,如圓形(Circle)、矩形(Rectangle)或菱形(Diamond),這樣整個軟件的體系結構就將如圖2所示。
圖2 ShapeFactory類用于創建各種幾何圖形的實例,其實現代碼如下所示:
代碼清單5:shapefactory.py
class ShapeFactory:
def factory(self, which):
if which == "Circle":
return Circle()
elif which == "Rectangle":
return Rectangle()
elif which == "Diamond":
return Diamond()
else:
return None
在ShapeFactory類中只定義了一個方法factory(),外界通過調用該方法,來創建其所需的幾何圖形對象,但如果所請求的類是系統所不支持的,則將返回None。在引入了工廠類之后,其它模塊如果想生成幾何圖形類的實例,只需調用ShapeFactory類的factory()方法就可以了:
fac = ShapeFactory()
shape = fac.factory("Diamond")
if shape != None:
shape.draw()
就樣就成功地將類是如何創建的這一實現細節向外界隱藏起來了,這就是簡單工廠模式所采取的基本策略。
三、一般結構
簡單工廠模式屬于類的創建型模式,適合用來對大量具有共同接口的類進行實例化,它可以推遲到運行的時候才動態決定要創建哪個類的實例
原文轉自:http://www.kjueaiud.com