前言
前面介紹了單例模式及工廠模式相關(guān)知識及示例,今天主要介紹的是抽象工廠模式,上一篇我們講了工廠模式。將創(chuàng)建對象的任務(wù)委托給子類,延遲創(chuàng)建。解決工廠中責(zé)任的劃分。實現(xiàn)具體工廠與產(chǎn)品之間的一一對應(yīng)。解決的是”單個對象”的問題。
華為工廠除了生產(chǎn)華為手機(jī)之外??隙ㄒ矔性涮椎某潆娋€和耳機(jī)。這時工廠對應(yīng)的是一套產(chǎn)品該如何解決了呢?顯然不再適合使用工廠模式了。今天將的抽象工廠模式將會比較好的解決此問題。抽象工廠模式解決的是”一系列對象”的問題、解決多套變化的問題。
抽象工廠模式介紹
一、來由
在我們編程的過程中難免會出現(xiàn)”一系列相互依賴對象”的創(chuàng)建問題,往往會有由于需要的改變增加或減少對象的創(chuàng)建。為了面對解決這種”一系列的相互依賴的對象”的創(chuàng)建工作的緊密耦合性,出現(xiàn)了其解決方案——抽象工廠模式。
二、意圖
提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類。
三、案例圖
?
?
四、與工廠模式區(qū)別
工廠模式:
1、解決”單個對象”的問題
2、工廠類與產(chǎn)品類一一對應(yīng)關(guān)系
抽象工廠模式:
1、解決”一系列對象”的問題
2、工廠類與產(chǎn)品類是一對多的關(guān)系(一對應(yīng)一系列想依賴的產(chǎn)品)
工廠模式講的是一個華為手機(jī)工廠生產(chǎn)一個華為手機(jī),要生產(chǎn)其他的產(chǎn)品需另加工廠。抽象工廠模式講的是一個華為手機(jī)工廠可以生產(chǎn)一系列的華為手機(jī)產(chǎn)品(手機(jī)、耳機(jī)、充電器)。
五、抽象工廠模式代碼示例
根據(jù)上一篇文章的事例我們進(jìn)行擴(kuò)展,進(jìn)一步講述抽象工廠模式的使用。抽象工廠模式我們工廠類對應(yīng)的多個產(chǎn)品的生產(chǎn)。華為手機(jī)工廠生產(chǎn)華為手機(jī)、華為耳機(jī)、華為充電器等。下面我們看看抽象工廠模式的具體實現(xiàn):
?
namespace Abstract_Factory { #region 抽象產(chǎn)品類 =============== /// <summary> ///
手機(jī)抽象類/// </summary> public abstract class Phone { public abstract string
CreatePhone(); }/// <summary> /// 耳機(jī)抽象類 /// </summary> public abstract class
Headset {public abstract string CreateHeadset(); } /// <summary> /// 充電器抽象類 ///
</summary> public abstract class Charger { public abstract string
CreateCharger(); }#endregion #region 華為具體產(chǎn)品類 =========== public class
HuaweiPhone : Phone {public override string CreatePhone() { return "華為手機(jī)一號現(xiàn)世";
} }public class HuaweiHeadset : Headset { public override string
CreateHeadset() {return "華為手機(jī)一號原配耳機(jī)"; } } public class HuaweiCharger : Charger {
public override string CreateCharger() { return "華為手機(jī)一號原配充電器"; } } #endregion
#region 小米具體產(chǎn)品類 =========== public class XiaomiPhone : Phone { public override
string CreatePhone() { return "小米手機(jī)一號現(xiàn)世"; } } public class XiaomiHeadset :
Headset {public override string CreateHeadset() { return "小米手機(jī)一號原配耳機(jī)"; } }
public class XiaomiCharger : Charger { public override string CreateCharger() {
return "小米手機(jī)一號原配充電器"; } } #endregion #region 抽象工廠類 =============== /// <summary>
/// 抽象工廠類 /// </summary> public abstract class AbstractFactory { public abstract
Phone GetPhone();public abstract Headset GetHeadset(); public abstract Charger
GetCharger(); }#endregion #region 華為具體工廠=============== public class
HuaweiFactory : AbstractFactory {public override Phone GetPhone() { return new
HuaweiPhone(); }public override Headset GetHeadset() { return new
HuaweiHeadset(); }public override Charger GetCharger() { return new
HuaweiCharger(); } }#endregion #region 小米具體工廠=============== public class
XiaomiFactory : AbstractFactory {public override Phone GetPhone() { return new
XiaomiPhone(); }public override Headset GetHeadset() { return new
XiaomiHeadset(); }public override Charger GetCharger() { return new
XiaomiCharger(); } }#endregion }
?
class Program { static void Main(string[] args) { ///華為工廠生產(chǎn)華為產(chǎn)品 HuaweiFactory
huaweiFactory =new HuaweiFactory(); var phone =
huaweiFactory.GetPhone().CreatePhone();var headset =
huaweiFactory.GetHeadset().CreateHeadset();var charger =
huaweiFactory.GetCharger().CreateCharger(); Console.WriteLine("華為產(chǎn)品生產(chǎn):" + phone
+"——" + headset + "——" + charger); ///小米工廠生產(chǎn)小米產(chǎn)品 XiaomiFactory xiaomiFactory =
new XiaomiFactory(); phone = xiaomiFactory.GetPhone().CreatePhone(); headset =
xiaomiFactory.GetHeadset().CreateHeadset(); charger=
xiaomiFactory.GetCharger().CreateCharger(); Console.WriteLine("小米產(chǎn)品生產(chǎn):" + phone
+"——" + headset + "——" + charger); Console.ReadLine(); } }
?
這是系列產(chǎn)品新增了一個魅族手機(jī),我們看看如何修改增加魅族手機(jī)的生產(chǎn):
#region 新增魅族手機(jī)需求=========== public class MeizuPhone : Phone { public override
string CreatePhone() { return "魅族手機(jī)一號現(xiàn)世"; } } public class MeizuHeadset :
Headset {public override string CreateHeadset() { return "魅族手機(jī)一號原配耳機(jī)"; } }
public class MeizuCharger : Charger { public override string CreateCharger() {
return "魅族手機(jī)一號原配充電器"; } } public class MeizuFactory : AbstractFactory { public
override Phone GetPhone() { return new MeizuPhone(); } public override Headset
GetHeadset() {return new MeizuHeadset(); } public override Charger GetCharger()
{return new MeizuCharger(); } } #endregion
?
///魅族工廠生產(chǎn)小米產(chǎn)品 MeizuFactory meizuFactory = new MeizuFactory(); phone =
meizuFactory.GetPhone().CreatePhone(); headset=
meizuFactory.GetHeadset().CreateHeadset(); charger=
meizuFactory.GetCharger().CreateCharger(); Console.WriteLine("魅族產(chǎn)品生產(chǎn):" + phone +
"——" + headset + "——" + charger);
這里我們可以發(fā)現(xiàn)新增系列產(chǎn)品(魅族系列)比較方便,而且吻合”開放擴(kuò)展——封閉修改”的原則。擴(kuò)展起來還是比較方便的,但是也是存在著一定的問題的。當(dāng)我們新增新的產(chǎn)品的時候,這個時候就需要去系列產(chǎn)品生產(chǎn)抽象工廠去增加產(chǎn)品的生產(chǎn)方法。同時也需要在各個子類中增加其方法。這也就違背了開閉原則。這也就是抽象方法的一個缺點所在。
使用場景及優(yōu)缺點
一、使用場景
1、在系統(tǒng)中如果存在一系列相互依賴的產(chǎn)品。這系列變化比較多。且存在著多套系列的產(chǎn)品的時候。我們就可以考慮使用抽象工廠模式了。
2、強(qiáng)調(diào)一系列相關(guān)的產(chǎn)品對象設(shè)計的時候。
3、一個系統(tǒng)由多個相互依賴項進(jìn)行配置且需要多個系統(tǒng)時。
二、優(yōu)點
1、當(dāng)一個產(chǎn)品系列,對個對象使用時,保證使用的是同系列中的對象
2、降低了具體產(chǎn)品和具體類及客戶端之間的耦合性。通過使用抽象類相關(guān)聯(lián)而不是具體類。
3、對系列產(chǎn)品的修改增加極其方便
三、缺點
1、在系列產(chǎn)品中新增產(chǎn)品困難并且違反了開閉原則
總結(jié)
到這里抽象工廠模式我們就暫時的介紹完了。今天呢又介紹了創(chuàng)建型中的一種設(shè)計模式,設(shè)計模式的學(xué)習(xí)之路還很漫長。一切都才剛剛開始。學(xué)習(xí)更重要的是靈活運(yùn)用,舉一反三。選擇適當(dāng)?shù)膱鼍叭ナ褂眠m當(dāng)?shù)哪J健6嗨伎计鋬?yōu)點缺點和使用場景。抽象工廠在針對于系列產(chǎn)品的修改增加時符合開閉原則。但是在系列產(chǎn)品中的產(chǎn)品修改增加的時候又違反了開閉原則。我們在使用每一種設(shè)計模式時都得慎重選擇。
? 只要認(rèn)為是對的就去做,堅持去做,不要在乎別人的看法,哪怕是錯,至少你有去做過證明曾經(jīng)你努力過。
?
?
C#設(shè)計模式系列目錄 <https://www.cnblogs.com/hulizhong/p/11394686.html>
?
歡迎大家掃描下方二維碼,和我一起踏上設(shè)計模式的闖關(guān)之路吧!
?
?
熱門工具 換一換