定義一個(gè)抽象工廠鸟蟹,然后實(shí)現(xiàn)若干個(gè)子類工廠泣洞,用于實(shí)例化不同的產(chǎn)品子類對(duì)象。
abstract class Factory
{
public ProductA CreateProductA();
public ProductB CreateProductB();
}
class Factory1 : Factory
{
override public ProductA CreateProductA()
{
return new ProductA1();
}
override public ProductB CreateProductB()
{
return new ProductB1();
}
}
class Factory2 : Factory
{
override public ProductA CreateProductA()
{
return new ProductA2();
}
override public ProductB CreateProductB()
{
return new ProductB2();
}
}
調(diào)用
Factory factory1 = new Factory1();
ProductA = factory1.CreateProductA();
ProductB = factory1.CreateProductB();
Factory factory2 = new Factory();
ProductA = factory2.CreateProductA();
ProductB = factory2.CreateProductB();
優(yōu)點(diǎn)
- 現(xiàn)有產(chǎn)品的子類產(chǎn)品擴(kuò)展方便
比如秀仲,ProductA衍生出新的子類產(chǎn)品ProductA3融痛。則只需要擴(kuò)展一個(gè)新的工廠Factory3即可,不需要修改原有的工廠類神僵。
缺點(diǎn)
- 新類型的產(chǎn)品無法擴(kuò)展雁刷,只能修改原有代碼
比如新添加一個(gè)產(chǎn)品,ProductC保礼。首先需要在抽象工廠Factory中添加接口:
public ProductC CreateProductC();
還要在所有工廠子類中實(shí)現(xiàn)這個(gè)接口沛励。違背了“開閉原則”。
舉例
如果想要封裝不同數(shù)據(jù)庫的差異炮障,首先定義了一個(gè)抽象數(shù)據(jù)庫工廠類DateBaseFactory目派,然后定義了基本的接口。之后繼承此抽象工廠胁赢,實(shí)現(xiàn)了不同類型的數(shù)據(jù)庫工廠企蹭,DataBaseFactoryMySQL, DataBaseFactoryMongo。
如果現(xiàn)在要支持SQLServer,則非常方便谅摄,新添加一個(gè)DataBaseFactorySQLServer即可徒河。
但此時(shí)要對(duì)數(shù)據(jù)庫添加新的操作,則要修改每一個(gè)類螟凭,添加相對(duì)的接口虚青。
改進(jìn)
從調(diào)用具體工廠的代碼可以看出,調(diào)用者雖然沒有與具體的產(chǎn)品類耦合螺男,但卻與具體的工廠類耦合了棒厘。為了解決這個(gè)問題,我們可以使用配置文件下隧,記錄要使用的工廠類字符串奢人,然后在代碼中使用反射動(dòng)態(tài)創(chuàng)建工廠對(duì)象,從而讓調(diào)用者也與具體的工廠類解藕淆院。
畢竟何乎,修改配置文件,要比修改代碼方便的多土辩。