定義:
抽象工廠模式,提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
結構圖:

AbstractProductA和AbstractProductB是兩個抽象產品,有兩種不同的實現。(User、Department)
ProductA1、ProductA2、ProductB1、ProductB2就是對兩個抽象產品的具體分類實現。(AccessUser、SqlserverUser、AccessDepartment、SqlserverDepartment)
Ifactory,抽象工廠接口。包含所有產品創建的抽象方法。
ConcreteFactory1、ConcreteFactory2,具體的工廠。
通常,運行時刻,創建一個ConcreteFactory類的實例,這個具體工廠再創建具有特定實現的產品對象。即,為創建不同的產品對象,客戶端使用不同的具體工廠。
示例:
用戶與數據庫交互的解耦。(即,業務邏輯與數據訪問解耦)

進階:添加訪問數據庫的用戶。



優點:
易於交換產品系列。由於具體工廠類在一個應用程序中只需要再初始化的時候出現一次。使得改變一個應用的具體工廠變得非常容易。只需要改變具體工廠即可使用不同的產品配置。(不能防止需求的更改,則讓改動變得最小)
讓具體的創建示例過程與客戶端分離。客戶端是通過他們的抽象接口操縱實例。產品的具體類名也被具體工廠的實現分離,不會出現在客戶代碼中。(客戶端只認識IUser、IDepartment,對於用SQL Server實現還是Access實現就不知道了)
開放-封閉原則、依賴倒轉原則
缺點:
增加用戶類(產品類)的時候,需要修改的地方多。(添加類:產品抽象類、產品實現類(多種方式對應多個類);添加方法:抽象工廠接口、抽象實現類(實現方式對應多個類))
修改實現方式的時候,n個產品調用實現同一實現方式時,需要修改n次。
編程是門藝術,這樣大批量的改動,顯然是非常丑陋的做法。
優化:
優化一:
簡單工廠。拋棄抽象工廠類、具體工廠類,用DataAccess類來取而代之。當修改工廠方式時,只需修改db的值即可。這樣客戶端不需要出現工廠方式,打到解耦的目的。


缺點:如果需要增加工廠方式。抽象工廠增加一個具體工廠類就可以了。現在,需要在DataAccess類中每個方法添加case
優化二:
依賴注入,反射:修改,增加都達到了解耦的目的。
反射格式:
![]()

將SqlserverUser用變量來處理,達到靈活更換的目的。之前實例化都是寫死在程序里的,而現在用了反射就可以用字符串來實例化對象,變量是可以更換的。更准確的說,將程序由編譯時轉為運行時。
結構圖如方式一。

優點:
修改工廠方式,只需修改db即可,達到對於修改盡量關閉的目的。增加工廠方式,只需在對應產品類添加具體實現類,並在DataAccess添加創建產品的方法即可。
反射+抽象工廠模式,解決了數據庫訪問時的可維護、可擴展的問題。
缺點:更換工廠方式時,還是需要改程序,重新編譯。
總結:switch或if是程序中的好東西,但在應對變化上,卻顯得老態龍鍾。反射技術的確可以很好地解決他們難以定對變化,難以維護、擴展的詬病。
優化三:
反射+配置文件:優化修改工廠方式時,需重新編譯。


擴展:
工廠方法模式:定義一個用於創建對象的接口,讓子類決定實例化哪個類。
所有在用簡單工廠的地方,都可以考慮用反射技術來去除switch或if,解除分支判斷帶來的耦合。
