〔本站副站發(fā)布,主站:designpatterns.cnblogs.com〕
○。背景與背景知識(shí)
這是昨天在QQ上舉的一個(gè)例子。本文并不是從頭講Factory Method模式,僅對(duì)其實(shí)現(xiàn)細(xì)節(jié)進(jìn)行討論。關(guān)于這個(gè)模式可以參考wayfarer和呂震宇的文章。
一。分析
因?yàn)镕actory Method(大寫的Factory Method表示模式名稱)模式的一個(gè)目的就是使得創(chuàng)建行為(factory method)(小寫的factory method表示創(chuàng)建行為方法)抽象化,由子類實(shí)現(xiàn),從而容易擴(kuò)展。一個(gè)純的Factory Method模式,其factory method是不能用static來(lái)實(shí)現(xiàn)的。通常Simple Factory模式才會(huì)由static來(lái)實(shí)現(xiàn)。
但是,一個(gè)Factory擁有一個(gè)static的創(chuàng)建方法是很誘人的。用戶在任何時(shí)候只要用類名(Factory的類名)既可以創(chuàng)建出需要的Product。wayfarer?的文章最后給出的DotNet的實(shí)現(xiàn)部分就是這樣的例子。呂震宇的另一篇文章?(關(guān)于Simple Factory模式)的回復(fù)中Walkdan給出的解決方案也是這樣的。從本質(zhì)上,這兩個(gè)例子都不是純的Factory Method模式或者Simple Factory模式,而是Simple Factory模式和Factory Method模式的組合應(yīng)用。
引用Walkdan的回復(fù):
Simple Factory最大的好處是把變化集中到了一處。另外,LightSimpleFactory.Create()里面的依賴關(guān)系也可以消除,我的做法是:
1. 聲明構(gòu)造子
public interface?ILightCreator
{
????Light?Create();
}
public class?BulbLightCreator:?ILightCreator
{
public?Light?Create()
????{
return new?BulbLight();
????}
}
.
2. 注冊(cè)構(gòu)造子
creators.Register("Bulb",?new?BulbLightCreator());
creators.Register("Tube",?new?TubeLightCreator());
.
3.?Simple Factory中創(chuàng)建對(duì)象?
public class?LightSimpleFactory.Create(string?lightType)
{
????ILightCreator?creator?=?creators.Find(lightType);
return?creator.Create();
}
構(gòu)造子其實(shí)就是Factory Method。這樣, 通過(guò)注冊(cè)構(gòu)造子,3.中原來(lái)的switch()過(guò)程被消除,依賴關(guān)系隨之解除。其中的Register(), Find()容易理解,方法就不寫了。
新的類型可通過(guò)新注冊(cè)構(gòu)造子來(lái)實(shí)現(xiàn)擴(kuò)展。當(dāng)然2中的注冊(cè)代碼僅僅是示例,完全可以放到配置文件中去實(shí)現(xiàn),比如:
<lightCreators>
<add?name="Bulb"?type="BulbLightCreator,
"/>
<add?name="Tube"?type="TubeLightCreator,
"/>
</lightCreators>
其ILightCreator繼承體系,是Factory Method模式。LightSimpleFactory和creators的關(guān)系Walkdan沒(méi)有說(shuō)明,也可實(shí)現(xiàn)為Strategy模式。
二。引申問(wèn)題
- 模式中factory method一定要是抽象的嗎? NO.你可以定義一個(gè)默認(rèn)的方法,生產(chǎn)某種Product。這樣即使Factory沒(méi)有子類也可以生產(chǎn)這種默認(rèn)產(chǎn)品。通常這種情況下Factory是一個(gè)接口,然后定義一個(gè)BasicFactory來(lái)生產(chǎn)BasicProduct。其他的Factory由BasicFactory派生。注意,往往Factory和Product是平行的繼承結(jié)構(gòu)。
- Factory Method解耦了client和concreteProduct,是不是又引入了client和concreteFactory的耦合? 這個(gè)問(wèn)題很好,答案是可能(《head first design patterns》一書(shū)中的例子就有這個(gè)問(wèn)題),但是client端不應(yīng)該依賴concreteFactory。如果依賴concreteFactory,那真是畫(huà)蛇添足了(見(jiàn)wayfarer的文章)。
- Factory Method模式的好處有哪些?
- 封裝了對(duì)象的創(chuàng)建。對(duì)象的創(chuàng)建如果使用new來(lái)完成,則與實(shí)現(xiàn)類(concreteProduct)是緊耦合的。Factory Method的創(chuàng)建行為factory method,返回Product接口,從而解耦了client和concreteProduct。
- 易于擴(kuò)展。相對(duì)于Simple Factory模式,F(xiàn)actory Method模式可以通過(guò)派生進(jìn)行擴(kuò)展。
三。結(jié)論
一個(gè)純的Factory Method模式其factory method不可以用static實(shí)現(xiàn),通過(guò)與其他模式結(jié)合使用可以進(jìn)行變通。而且通常情況下Factory Method模式都會(huì)與其他模式相結(jié)合。Abstract Factory模式通常就是用Factory Method模式來(lái)實(shí)現(xiàn)。