C# 设计模式——简单工厂模式、工厂模式、抽象工厂模式
1、前言
上一篇寫了設(shè)計(jì)模式原則有助于我們開發(fā)程序的時(shí)候能寫出高質(zhì)量的代碼(牽一發(fā)而不動(dòng)全身),這個(gè)系列還是做個(gè)筆記溫習(xí)一下各種設(shè)計(jì)模式,下面就看看簡(jiǎn)單工廠模式、工廠模式、抽象工廠模式。
2、簡(jiǎn)單工廠模式
其實(shí)我們可以這么理解簡(jiǎn)單工廠模式,就是專門負(fù)責(zé)生產(chǎn)對(duì)象的一個(gè)類,作用就是創(chuàng)建具體產(chǎn)品的實(shí)例。我們平時(shí)創(chuàng)建創(chuàng)建一個(gè)對(duì)象的時(shí)候通常都是new出來(lái)的,此時(shí)這個(gè)類就依賴與這個(gè)對(duì)象,說(shuō)白了就是耦合度過(guò)高啦。需求變化的時(shí)候我們不得不去修改此類的源碼。這時(shí)候就要用面向?qū)ο螅∣O)的思想去處理這個(gè)問(wèn)題。把變化大的類封裝起來(lái),實(shí)現(xiàn)就不去動(dòng)它。下面看個(gè)栗子,就生產(chǎn)、制造不同的汽車分析簡(jiǎn)單工廠模式的作用。
/// <summary>
/// 車 抽象類
/// </summary>
public abstract class Car
{
/// <summary>
/// 制造車--抽象方法
/// </summary>
public abstract void Make();
/// <summary>
/// 賣車--抽象方法
/// </summary>
public abstract void Sale();
}
/// <summary>
/// 奧迪車
/// </summary>
public class ADCar : Car
{
public override void Make()
{
Console.WriteLine("制造了一輛奧迪車");
}
public override void Sale()
{
Console.WriteLine("銷售了一輛奧迪車");
}
}
/// <summary>
/// 奔馳車
/// </summary>
public class BCCar : Car
{
public override void Make()
{
Console.WriteLine("制造了一輛奔馳車");
}
public override void Sale()
{
Console.WriteLine("銷售了一輛奔馳車");
}
}
看客戶端的調(diào)用
Car c = new ADCar();
c.Make();
c.Sale();
Console.WriteLine("\n");
Car b = new BCCar();
b.Make();
b.Sale();
我們可以看都是通過(guò)new一個(gè)ADCar 來(lái)創(chuàng)建一個(gè)實(shí)例, 想要奔馳的一樣的要new一個(gè)出來(lái) 我想要n個(gè)那不是炸鍋了。所以這里就創(chuàng)建一個(gè)車的簡(jiǎn)單工廠類。讓這個(gè)工廠類來(lái)創(chuàng)建Car實(shí)例。這里的switch是C#的語(yǔ)法糖,感覺(jué)是不是有點(diǎn)香。
/// <summary>
/// 車的工廠類
/// </summary>
public class CarFactory
{
public static Car OpCar(string carName)
{
Car? car = null;
var ret = carName switch
{
"AD" => car=new ADCar(),
"BC" => car=new BCCar(),
_ => car=new ADCar()
};
return ret;
}
}
//客戶端調(diào)用
Car cc = CarFactory.OpCar("AD");
cc.Make();
cc.Sale();
Car cc1 = CarFactory.OpCar("BC");
cc1.Make();
cc1.Sale();
這時(shí)候是不是就可以了,解決了客戶端太過(guò)于依賴具體對(duì)象的問(wèn)題,別急如果我再來(lái)一個(gè)寶馬 就要還添加一個(gè)繼承Car的BMCar 還要在 CarFactory的OpCar里面再加一個(gè)判斷。按照開閉原則來(lái)說(shuō)添加類沒(méi)有啥影響,但是修改了CarFactory里面OpCar的代碼就不符合開閉原則了。下面的工廠模式就專門解決這個(gè)問(wèn)題。
3、工廠模式
在簡(jiǎn)單工廠模式中系統(tǒng)難以擴(kuò)展且違背了開閉原則,這樣使得簡(jiǎn)單工廠的實(shí)現(xiàn)邏輯過(guò)于復(fù)雜。工廠模式就是把具體創(chuàng)建類的實(shí)例中放在子工廠類中,工廠類不再負(fù)責(zé)所有產(chǎn)品的創(chuàng)建工廠類只提供創(chuàng)建實(shí)例。還是看上面的栗子我們加一個(gè)抽象工廠類出來(lái),讓不同的品牌去繼承
/// <summary>
/// 車工廠類
/// </summary>
public abstract class CarFactory1
{
/// <summary>
/// 抽象方法
/// </summary>
public abstract Car OpCar();
}
/// <summary>
/// 奧迪工廠
/// </summary>
public class ADCarFactory1 : CarFactory1
{
public override Car OpCar()
{
return new ADCar();//在具體的工廠中實(shí)例化產(chǎn)品
}
}
/// <summary>
/// 奔馳工廠
/// </summary>
public class BCCarFactory1 : CarFactory1
{
public override Car OpCar()
{
return new BCCar();//在具體的工廠中實(shí)例化產(chǎn)品
}
}
//客戶端調(diào)用
CarFactory1 cf = new ADCarFactory1();
Car car = cf.OpCar();
car.Make();
car.Sale();
CarFactory1 cf2 = new BCCarFactory1();
Car car2 = cf2.OpCar();
car2.Make();
car2.Sale();
效果跟上面一樣的,這里是不是就實(shí)現(xiàn)了新增一個(gè)寶馬的話不用修改Factory里面的代碼了只要在創(chuàng)建一個(gè)BMCarFactory1跟BMCar就可以了。我們要獲取一個(gè)產(chǎn)品的時(shí)候我們就獲取一個(gè)具體的工廠來(lái)實(shí)例它。 它是不是解決了簡(jiǎn)單工廠的不足也符合了開閉原則。問(wèn)題也來(lái)了如果我不單單要銷售車、賣車 搞大了我還要賣飛機(jī)賣火箭咋搞。這種不可能再去創(chuàng)建無(wú)數(shù)個(gè)工廠嘛。來(lái)看看抽象工廠模式。
4、抽象工廠模式
工廠模式它功能單一點(diǎn)只針對(duì)一個(gè)品牌,解決不了一系列的問(wèn)題,賣火箭、賣飛機(jī)等等這些不同的品牌。如果我們?cè)谠O(shè)計(jì)程序中顯然工廠模式已經(jīng)滿足不了我們的需求了。抽象工廠模式就能很好的解決這個(gè)問(wèn)題。這里我們還是新增一個(gè)抽象類,他提供制造、銷售汽車的同事也提供制造銷售飛機(jī)。實(shí)現(xiàn)方法只要實(shí)現(xiàn)自己品牌的的產(chǎn)品就可以了。
/// <summary>
/// 產(chǎn)品抽象類
/// </summary>
public abstract class PcFactory
{
/// <summary>
/// 車
/// </summary>
/// <returns></returns>
public abstract Car OpCar();
/// <summary>
/// 飛機(jī)
/// </summary>
/// <returns></returns>
public abstract Plan OpPlan();
}
/// <summary>
/// 奧迪pc工廠
/// </summary>
public class ADPcFactory : PcFactory
{
public override Car OpCar()
{
return new ADCar();
}
public override Plan OpPlan()
{
return new ADPlan();
}
}
/// <summary>
/// 奔馳pc工廠
/// </summary>
public class BCPcFactory : PcFactory
{
public override Car OpCar()
{
return new BCCar();
}
public override Plan OpPlan()
{
return new BCPlan();
}
}
//客戶端調(diào)用
PcFactory pf = new ADPcFactory();
Car adc = pf.OpCar();
Plan adc2 = pf.OpPlan();
adc.Make();
adc.Sale();
adc2.Make();
adc2.Sale();
PcFactory pf2 = new BCPcFactory();
Car abc = pf2.OpCar();
Plan abc2 = pf2.OpPlan();
abc.Make();
abc.Sale();
abc2.Make();
abc2.Sale();
我們可以看出抽象工廠跟工廠的區(qū)別就在于它能生產(chǎn)多種產(chǎn)品(車、飛機(jī))工廠只能是單一的產(chǎn)品(車)。抽象類只注重創(chuàng)建的多個(gè)產(chǎn)品,不會(huì)關(guān)心具體的實(shí)現(xiàn)是什么。實(shí)現(xiàn)又是不通的產(chǎn)品工廠實(shí)現(xiàn)的。這樣的話客戶端也從具體的產(chǎn)品中解耦出來(lái)。
5、總結(jié)
簡(jiǎn)單工廠模式
優(yōu)點(diǎn):降低刻度段與具體產(chǎn)品的耦合度,實(shí)現(xiàn)new讓工廠類去完成,也提高了代碼的復(fù)用率。
缺點(diǎn):違反了開閉原則系統(tǒng)擴(kuò)展困難,而且工廠類集中了所有的業(yè)務(wù)邏輯一旦出問(wèn)題整個(gè)系統(tǒng)都要受牽連。
工廠模式
優(yōu)點(diǎn):符合開閉原則新增功能不會(huì)區(qū)修改以前的代碼。
缺點(diǎn):產(chǎn)品功能單一寫車的功能只能弄車,而不能加飛機(jī)、火箭的操作。
抽象工廠模式
優(yōu)點(diǎn):降低系統(tǒng)耦合度利于維護(hù)擴(kuò)展,對(duì)于加系列產(chǎn)品符合開閉原則;
缺點(diǎn):對(duì)于功能添加又不符合開閉原則了??粗遣皇歉鷥?yōu)點(diǎn)有沖突。這樣說(shuō)吧我現(xiàn)在要加一個(gè)寶馬類不用修改業(yè)務(wù)邏輯添加一個(gè)BMCarFactory1跟BMCar就可以了。這是系列問(wèn)題。如果我要加一個(gè)銷毀的方法(之前就定義了制作、銷售)那是不是還要在抽象類Car、Plan里面加一個(gè)抽象方法 繼承里面的通通都要實(shí)現(xiàn)它。所以程序設(shè)計(jì)之初沒(méi)有考慮到后面一個(gè)一個(gè)的改很麻煩。
一個(gè)系統(tǒng)要求不被所有客戶端依賴到具體的實(shí)現(xiàn)這是所有工廠模式的應(yīng)用的前提,這就要具體問(wèn)題具體分析了。不可能說(shuō)我要打印一個(gè)Holl Word還來(lái)搞設(shè)計(jì)模式嘛,高射炮打蚊子沒(méi)有必要。各種模式都有好有壞,相對(duì)論就是這么說(shuō)的,你得到一些的時(shí)候必然會(huì)失去一些,快樂(lè)要有悲傷作伴,雨過(guò)自然天晴嗎。加了設(shè)計(jì)模式以后代碼量肯定要上去的帶給我們方便的同時(shí)也會(huì)增加風(fēng)險(xiǎn)。以前不解為啥要?jiǎng)?chuàng)建那么多項(xiàng)目,文件夾,現(xiàn)在想想就那么回事了。
PS:流年似水,歲月如歌,承受委屈是一種胸懷,接受誤解是一種心懷,這個(gè)世界上失去什么東西都不可怕,惟一可怕的是失去你的心,失去你的勇氣,只要你堅(jiān)韌不拔地奮斗,只要你眼睛看向未來(lái),生命就永遠(yuǎn)屬于你,生命的輝煌也一定永遠(yuǎn)屬于你。
版權(quán)聲明:本文為 魏楊楊 原創(chuàng)文章并發(fā)布到博客園, 除了【萬(wàn)仟網(wǎng)】外, 其他平臺(tái)歡迎轉(zhuǎn)載,但必須在文章頁(yè)面明顯位置寫明作者和出處,非常感謝。技術(shù)交流QQ群 99210270
微信掃一掃關(guān)注我公眾號(hào)
一起學(xué)習(xí),一起進(jìn)步
總結(jié)
以上是生活随笔為你收集整理的C# 设计模式——简单工厂模式、工厂模式、抽象工厂模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 烤箱怎么使用 烤箱的基本操作和使用技巧?
- 下一篇: 厨房收不下?美国收纳女王盘活8大橱柜设计