C#設(shè)計(jì)模式之工廠模式
這是我們用得比較多的一種設(shè)計(jì)模式,也是23種標(biāo)準(zhǔn)設(shè)計(jì)模式之一,使用前面講的簡(jiǎn)單工廠設(shè)計(jì)模式,遇到具體產(chǎn)品經(jīng)常變換時(shí)就不太適合了,違反了開閉設(shè)計(jì)原則;怎么才能避免修改工廠類呢?工廠方法模式可以做到。
工廠方法模式要求我們應(yīng)該有一個(gè)抽象的工廠類,我們知道盡量使用抽象類或接口來(lái)定義就可以達(dá)到一個(gè)開閉原則的效果,這樣我們?cè)诔橄蟮墓S類定義一個(gè)生產(chǎn)產(chǎn)品的方法,這個(gè)方法就是工廠方法,這也是工廠方法模式的由來(lái),他具體的行為會(huì)有他的子類或?qū)崿F(xiàn)類來(lái)實(shí)現(xiàn)。如果想生產(chǎn)某種產(chǎn)品,就定義一個(gè)新的產(chǎn)品,新的產(chǎn)品工廠類,這樣就實(shí)現(xiàn)了不同的產(chǎn)品進(jìn)行一個(gè)不同的創(chuàng)建,這樣如果有信的產(chǎn)品,只需要添加新的工廠類,原來(lái)寫好的代碼不會(huì)發(fā)生變化,這種方式符合開閉原則,可擴(kuò)展比較好?!?/p>
添加一個(gè)具體產(chǎn)品,只需要在添加一個(gè)具體產(chǎn)品的工廠類實(shí)現(xiàn)抽象工廠類,不需要修改原來(lái)的代碼
示例代碼:
抽象產(chǎn)品類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /* 動(dòng)物抽象類 * 抽象產(chǎn)品 */ public abstract class Animal { public abstract void Eat(); } }
抽象工廠類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /* 動(dòng)物抽象工廠類 */ public abstract class AnimalFactory { public abstract Animal GetAnimal(); } }
生產(chǎn)狗的具體工廠類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /// <summary> /// 具體工廠:生成狗 /// </summary> public class DogFactory :AnimalFactory { public override Animal GetAnimal() { return new Dog(); } } }
生產(chǎn)企鵝的具體工廠類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /// <summary> /// 具體工廠:生成企鵝 /// </summary> public class PenguinFactory :AnimalFactory { public override Animal GetAnimal() { return new Penguin(); } } }
具體產(chǎn)品狗類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /* 具體的產(chǎn)品類,實(shí)現(xiàn)抽象產(chǎn)品類 */ public class Dog:Animal { // 實(shí)現(xiàn)抽象方法 public override void Eat() { Console.WriteLine("狗在吃飯!"); } } }
具體產(chǎn)品企鵝類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /* 具體產(chǎn)品類,實(shí)現(xiàn)抽象產(chǎn)品類 */ public class Penguin : Animal { // 實(shí)現(xiàn)抽象方法 public override void Eat() { Console.WriteLine("企鵝在吃飯!"); } } }
客戶端調(diào)用:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { class Program { static void Main(string[] args) { AnimalEat(new DogFactory()); Console.ReadKey(); } static void AnimalEat(AnimalFactory af) { Animal am = af.GetAnimal(); am.Eat(); } } }
類圖:
如果想在增加一個(gè)Cat類,只需要增加一個(gè)具體的Cat類實(shí)現(xiàn)Animal類的方法,增加一個(gè)具體的Cat工廠類實(shí)現(xiàn)抽象工廠類即可,不需要在修改已經(jīng)寫好的代碼,符合開閉原則。
使用接口的方式實(shí)現(xiàn)工廠模式
需求:使用面向?qū)ο蟮姆绞皆O(shè)計(jì)一個(gè)系統(tǒng),描述使用卡車從事貨運(yùn),使用公共汽車從事客運(yùn)。使用工廠模式實(shí)現(xiàn)。
1、汽車接口:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /// <summary> /// 汽車接口 /// </summary> public interface ICar { /// <summary> /// 描述汽車從事的活動(dòng) /// </summary> void Work(); } }
2、分別定義卡車(Truck)和公共汽車(Bus)類實(shí)現(xiàn)汽車接口(ICar)里面的Work()方法
Truck類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /// <summary> /// 卡車類 /// </summary> public class Truck : ICar { /// <summary> /// 卡車從事的活動(dòng) /// </summary> public void Work() { Console.WriteLine("卡車從事貨運(yùn)"); } } }
Bus類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /// <summary> /// 公共汽車類 /// </summary> public class Bus:ICar { /// <summary> /// 公共汽車從事的活動(dòng) /// </summary> public void Work() { Console.WriteLine("公共汽車從事客運(yùn)"); } } }
3、定義汽車的工廠接口(ICarFactory):
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /// <summary> /// 汽車工廠接口 /// </summary> public interface ICarFactory { ICar GetCar(); } }
4、分別定義卡車工廠(TruckFactory)和公共汽車工廠(BusFactory)實(shí)現(xiàn)ICarFactory接口
TruckFactory工廠:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /// <summary> /// 卡車工廠接口 /// </summary> public class TruckFactory:ICarFactory { /// <summary> /// 返回卡車類 /// </summary> /// <returns></returns> public ICar GetCar() { return new Truck(); } } }
BusFactory工廠:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { /// <summary> /// 公共汽車工廠 /// </summary> public class BusFactory:ICarFactory { /// <summary> /// 返回公共汽車類 /// </summary> /// <returns></returns> public ICar GetCar() { return new Bus(); } } }
5、主程序調(diào)用:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 工廠模式 { class Program { static void Main(string[] args) { CarWork(new TruckFactory()); Console.ReadKey(); } /// <summary> /// 根據(jù)汽車工廠返回具體的汽車類 /// </summary> /// <param name="cf"></param> static void CarWork(ICarFactory cf) { ICar c = cf.GetCar(); c.Work(); } } }
6、程序運(yùn)行結(jié)果
代碼下載地址:點(diǎn)擊下載
到此這篇關(guān)于C#設(shè)計(jì)模式之工廠模式的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
visio二次開發(fā)--判斷文檔是否已發(fā)生變化(變化就加星號(hào)*)
最近做一個(gè)故障樹診斷的項(xiàng)目,用visio二次開發(fā),可以同時(shí)打開多個(gè)繪制的故障樹圖形文檔。項(xiàng)目中需要實(shí)現(xiàn)判斷文檔是否發(fā)生變化,這是很多編輯軟件的基本功能,變化了就加個(gè)星號(hào)*2013-04-04逐步講解快速排序算法及C#版的實(shí)現(xiàn)示例
快速排序在時(shí)間復(fù)雜度同為O(N*logN)的幾種排序方法中效率較高,因而比較常用,接下來(lái)這里就來(lái)逐步講解快速排序算法及C#版的實(shí)現(xiàn)示例2016-06-06C#實(shí)現(xiàn)通過(guò)ffmpeg從flv視頻文件中截圖的方法
這篇文章主要介紹了C#實(shí)現(xiàn)通過(guò)ffmpeg從flv視頻文件中截圖的方法,實(shí)例分析了C#使用ffmpeg操作flv文件的技巧,需要的朋友可以參考下2015-03-03C#判斷一個(gè)字符串是否是數(shù)字或者含有某個(gè)數(shù)字的方法
這篇文章主要介紹了C#判斷一個(gè)字符串是否是數(shù)字或者含有某個(gè)數(shù)字的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-06-06C# DateTime與時(shí)間戳轉(zhuǎn)換實(shí)例
本篇文章主要介紹了C# DateTime與時(shí)間戳轉(zhuǎn)換實(shí)例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06C#不重復(fù)輸出一個(gè)數(shù)組中所有元素的方法
這篇文章主要介紹了C#不重復(fù)輸出一個(gè)數(shù)組中所有元素的方法,涉及C#針對(duì)數(shù)組的遍歷、校驗(yàn)及排序等操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08