Dot NET設計模式—反射工廠
如果採用傳統方式實現了簡單工廠、工廠方法和抽象工廠在有些場合下如此處理,程式碼會變得冗餘並且難以維護。
假設我們需要建立一種交通工具,可以是汽車、火車或者輪船,結構如圖所示。
我們可以採用簡單工廠,通過引數指示建立所需要的物件型別。如果增加子類,例如卡車和轎車等,則必須增加引數的相應的程式碼。如果子類層次很多,則會使程式變得難以維護如果用簡單工廠實現上面的結構,則顯然很煩瑣。
當然我們可以採用工廠方法來實現,即定義一個產生交通工具的介面,然後在子類中實現建立具體的子類。程式碼如下:
採用介面定義了抽象的工廠方法
Function CreateAVehicle() As Vehicle `建立一個交通工具
End Interface
` 具體的建立由子類決定
public Class CreateCar
Implements CreateCar
Public Function CreateAVheicle() AsVehicle Implements
CreateVehicle.CreateAVehicle
Return New Car
End Function
End Class
這就是工廠方法。如果我們希望增加一個新的交通工具,不僅需要實現工具介面,還需要實現產生交通工具的工廠方法。下面是船的具體工廠方法:
Implements CreateVehicle
Public Function CreateAVehicle() As Vehicle Implements
CreateVehicle.CreateAVehicle
Return New Boat
End Function
End Class
顯然,如果我們需要產生數十種交通工具則需要有數十個具體的工廠類。而這些工廠類的區別僅僅是返回相應的類的例項,所以為維護帶來了麻煩。如果需要在介面中增加一個帶引數的建立方法則所有的子類都不得需要修改。
在這個場合下,採用抽象工廠與工廠方法沒有區別。因為這裡並不涉及產品線,抽象工廠並不能解決其中有的問題。當然,如果每種交通工具都要有對應的車站,則要使用抽象工廠,但是將會更復雜。
2.採用反射技術簡化工廠類
有沒有可能將需要建立類的型別傳遞到工廠方法中,由工廠方法根據型別返回相應的例項?
解決這個問題的關鍵是需要動態決定需要建立的類,這不是設計模式能解決的問題屬於軟體平臺的功能範疇。.NET可以提供相應的功能,即反射技術。
我們首先檢視採用反射技術實現簡化的例項:
Public Class CreateVehicleByType
Implements CreateVehicle
Private VeicleType As Type
Public Sub New(ByVal t As Type)
VeicleType = t
End Sub
Public Function CreateAVehicle() As Vehicle Implements
CreateVehicle.CreateAVehicle
Dim objConstructor As ConstructorInfo =
VeicleType.GetConstructor(System.Type.EmptyTypes)
Dim c As Vehicle = Ctype(objConstructou.Invoke(Nothing),Vehicle)
Return c
End Function
End Class
在使用時,只要在建立時帶入需要建立的類的型別:
System.EventArgs) Handles btCreateBytype.Clik
`根據選擇建立一個交通工具並執行GO
Dim v As Vehicle `我們不知道需要建立的具體交通工具
Dim f As CreateVehicle
If rCar.Checked Then
F = New CreateVehicleByType(GetType(car))
End If
If rTrain.Checked Then
F = New CreateVehicleByType(GetType(Train))
End If
If rBoat.Checked Then
F = New CreateVehicleByType(GetType(Boat))
End If
If rBus.Checked Then
F = New CreateVehicleByType(GetType(Boat))
End If
V = f.CreateAVehicle
`執行GO指令
lbGO.Text = v.Go
End Sub
通過採用反射技術,我們將4個類簡化為一個類,並且在新增型別時不需要新的建立這樣,我們得到了簡化的工廠,可以將其稱為“反射工廠”。
3.對簡單工廠的改進
簡單工廠通過引數決定建立的型別,這些引數是在程式設計時預設的。因此在編譯後就無法修改,讓我們回顧程式碼:
我們可以將這個工廠改造為反射工廠:
Public Shared Function CreateDB(ByVal strType As string, ByVal strConnString AsString) As _ clsAbstractDB
Select Case strType.ToUpper
Case “ORACLE”
Dim myOracle As clsoracleDB
MyOracle = New clsOracleDB(strConnString)
Return myOracle
Case “SQLSERVER”
Dim mysqlserver As clsSQLServerDB
Mysqlserver = New clsSQLServerDB(strConnString)
Return mysqlserver
Case Else
Dim myoledb As clsOLEDB
Myoledb = New clsOLEDB(strConnString)
Return myoledb
End Select
End Function
End Class
這樣解決了簡單工廠必須依賴每個具體產品的問題,將表態依賴變為動態繫結.當引入新的資料庫型別時,不需要修改工廠即可滿足需要。
4.反射與工廠方法
如果工廠方法僅僅是為了獲得某個產品的例項,那麼完全可以使用反射技術來實現工廠方法。這樣解決了工廠方法的潛在問題,即當增加產品類時,必須增加相應的子類。
然而當工廠方法所存在的類不僅是例項化產品時,採用反射不一定是好辦法,因為可能使問題變得複雜。
5.反射與抽象工廠
可以採用反射來實現抽象工廠,這時抽象工廠可能變成了使用反射技術的具體工廠,不再有子類存在。建立交通系統的例項可以用如下的程式碼來寫:
'
'VehicleSystemReflectionFactory 採用反射技術的工廠。
'
Public Class VehicleSystemReflectionFactory
Dim vehicleType As String
Dim vehicleStationType As String
Public Sub New(ByVal vt As String, ByVal vst As String)
Me.vehicleType = vt
Me.vehicleStationType = vst
End Sub
Public Function GetVehicle() As Vehicle
Return CType(createbytype(Me.vehicleType), Vehicle)
End Function
Public Function GetVehicleStation() As VehicleStation
Return CType(createbytype(Me.vehicleStationType), VehicleStation)
End Function
Private Function createbytype(ByVal vt As String) As Object
Dim tt As Type
tt = Type.GetType(vt)
Dim ci As ConstructorInfo
ci = tt.GetConstructor(System.Type.EmptyTypes)
Dim null As System.DBNull
Return ci.Invoke(null)
End Function
End Class
這種情況下,抽象工廠就變為了只有一個類的反射工廠。
6.反射工廠的使用效果
使用反射工廠的優點是極大地減少了工廠類的數量、降低了程式碼的冗餘,並且系統更容易擴充套件,在增加新型別後,不需要修改工廠類。
使用反射工廠的代價是工廠與產品之間的依賴關係不明顯,由於是動態繫結,因此理論上可以用一個工廠完成很多型別的例項化,從而使得程式碼 不容易理解。另外增大了測試難度,建立是動態完成的,測試用例的編寫和測試執行要比傳統的工廠困難。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-608292/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 反射與工廠設計模式反射設計模式
- Java - 反射機制與工廠設計模式Java反射設計模式
- 設計模式-工廠模式二(工廠方法模式)設計模式
- 設計模式-簡單工廠、工廠方法模式、抽象工廠模式設計模式抽象
- 設計模式----工廠設計模式設計模式
- 設計模式-工廠設計模式設計模式
- 【設計模式】工廠模式設計模式
- 設計模式 —— 工廠模式設計模式
- 設計模式-工廠模式設計模式
- 設計模式(工廠模式)設計模式
- 設計模式——工廠模式設計模式
- 設計模式----工廠模式設計模式
- 設計模式之工廠方法模式|抽象工廠模式設計模式抽象
- 工廠設計模式設計模式
- C# 設計模式(1)——簡單工廠模式、工廠模式、抽象工廠模式C#設計模式抽象
- 設計模式之工廠模式!深入解析簡單工廠模式,工廠方法模式和抽象工廠模式設計模式抽象
- 設計模式學習(二)工廠模式——抽象工廠模式設計模式抽象
- 設計模式——抽象工廠模式設計模式抽象
- 設計模式 —— 抽象工廠模式設計模式抽象
- PHP設計模式-- 工廠模式PHP設計模式
- 設計模式-抽象工廠模式設計模式抽象
- Java設計模式(工廠模式)Java設計模式
- Java設計模式--工廠模式Java設計模式
- Java 設計模式(工廠模式)Java設計模式
- java設計模式-工廠模式Java設計模式
- 設計模式 - 工廠方法模式設計模式
- 設計模式之工廠模式設計模式
- java設計模式 – 工廠模式Java設計模式
- 設計模式 #2 (工廠模式)設計模式
- 設計模式之【工廠模式】設計模式
- 設計模式-工廠方法模式設計模式
- 設計模式~~~工廠方法模式設計模式
- PHP設計模式_工廠模式PHP設計模式
- 設計模式——工廠方法模式設計模式
- 設計模式(四)工廠模式設計模式
- Java設計模式:工廠模式Java設計模式
- 設計模式(三)——工廠模式設計模式
- 【設計模式】工廠方法模式設計模式