園子里關于23種設計模式的博文已經可以說是成千上萬、車載斗量、屯街塞巷、不計其數、數不勝數、摩肩接踵、汗牛充棟、車水馬龍、門庭若市、琳瑯滿目直至讓人眼花繚亂了。在這樣的大環境下之所以來寫設計模式類的博文,并不是像一些"非主流"的愛情觀那樣"寧缺毋濫"。 只是其一呢,因為相當于給自己做一個總結,加深一下自己這方面的認識,因為掌握了和把它寫出來我感覺后者還可以對技能有一個提升,其二呢是因為最近公司有一個內部的training需要講設計模式。
1.介紹:
2.延伸:
3.模擬場景:
歐美主導的以賽車為主題的系列電影《速度與激情》系列相信大家都看過,里面的男主角(zhǔ jué,加個拼音,經常聽到有人說什么主腳主腳的,雖然之前我也不確定是zhǔ jué還是主腳,但是我沒念過主腳,我在不確定的情況下我都是念男一號)范·迪塞爾在每一集里面做不同的事情都是開不同的車子,相信大家都覺得很酷吧。
人家酷也沒辦法,誰叫人家是大佬呢。這里我們試想一下,如果這是一套程序,我們該怎么設計?每次不同的畫面或者劇情范·迪塞爾都需要按照導演的安排開不一樣的車,去參加賽車需要開的是跑車,可能導演就會說下一場戲:范·迪塞爾下一場戲需要開跑車(參數),要去參加五環首屆跑車拉力賽,這時候場務(工廠類)接到導演的命令(跑車參數)后需要從車庫開出一輛跑車(具體產品)交到范·迪塞爾手上讓他去準備五環首屆跑車拉力賽。這套程序的整個生命周期就算完成了。(什么?沒完成?難不成你還真想來個五環首屆跑車拉力賽了啊:)
根據導演不同的指令,開的車是不一樣的,但是車都是在車庫中存在的。車都屬于同一種抽象,車庫里所有的車都有自己的特征,這些特征就是條件。導演發出指令的時候,只要告訴場務特征,場務就知道提什么車。這就簡單工廠模式的典型案例。
4.簡單工廠UML類圖: (UML圖是我用windows自帶的paint手工畫的,所以可能不是很專業)
5.代碼演示:
抽象產品類代碼:
namespace CNBlogs.DesignPattern.Common{ /// <summary> /// 抽象產品類: 汽車 /// </summary> public interface ICar { void GetCar(); }}
具體產品類代碼:
namespace CNBlogs.DesignPattern.Common{ public enum CarType { SportCarType = 0, JeepCarType = 1, HatchbackCarType = 2 } /// <summary> /// 具體產品類: 跑車 /// </summary> public class SportCar : ICar { public void GetCar() { Console.WriteLine("場務把跑車交給范·迪塞爾"); } } /// <summary> /// 具體產品類: 越野車 /// </summary> public class JeepCar : ICar { public void GetCar() { Console.WriteLine("場務把越野車交給范·迪塞爾"); } } /// <summary> /// 具體產品類: 兩箱車 /// </summary> public class HatchbackCar : ICar { public void GetCar() { Console.WriteLine("場務把兩箱車交給范·迪塞爾"); } }}
簡單工廠核心代碼:
namespace CNBlogs.DesignPattern.Common{ public class Factory { public ICar GetCar(CarType carType) { switch (carType) { case CarType.SportCarType: return new SportCar(); case CarType.JeepCarType: return new JeepCar(); case CarType.HatchbackCarType: return new HatchbackCar(); default: throw new Exception("愛上一匹野馬,可我的家里沒有草原. 你走吧!"); } } }}
客戶端調用代碼:
//------------------------------------------------------------------------------// <copyright file="// Copyright (C) 2015-2016 All Rights Reserved// 原博文地址: http://www.49028c.com/toutou/// 作 者: 請叫我頭頭哥// </copyright> //------------------------------------------------------------------------------namespace CNBlogs.DesignPattern{ using System; using CNBlogs.DesignPattern.Common; class Program { static void Main(string[] args) { ICar car; try { Factory factory = new Factory(); Console.WriteLine("范·迪塞爾下一場戲開跑車。"); car = factory.GetCar(CarType.SportCarType); car.GetCar(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } }}
簡單工廠的簡單案例就這么多,真正在項目實戰的話可能還有需要改進和擴展的地方。因需求而定吧。
6.簡單工廠的優點/缺點:
1.介紹:
2.定義:
3.延伸:
4.模擬場景:
5.工廠方法UML類圖: (UML圖是我用windows自帶的paint手工畫的,所以可能不是很專業
6.代碼演示:
抽象工廠代碼:
namespace CNBlogs.DesignPattern.Common{ public interface IFactory { ICar CreateCar(); }}
抽象產品代碼:
namespace CNBlogs.DesignPattern.Common{ public interface ICar { void GetCar(); }}
具體工廠代碼:
namespace CNBlogs.DesignPattern.Common{ /// <summary> /// 具體工廠類: 用于創建跑車類 /// </summary> public class SportFactory : IFactory { public ICar CreateCar() { return new SportCar(); } } /// <summary> /// 具體工廠類: 用于創建越野車類 /// </summary> public class JeepFactory : IFactory { public ICar CreateCar() { return new JeepCar(); } } /// <summary> /// 具體工廠類: 用于創建兩廂車類 /// </summary> public class HatchbackFactory : IFactory { public ICar CreateCar() { return new HatchbackCar(); } }}
具體產品代碼:
namespace CNBlogs.DesignPattern.Common{ /// <summary> /// 具體產品類: 跑車 /// </summary> public class SportCar : ICar { public void GetCar() { Console.WriteLine("場務把跑車交給范·迪塞爾"); } } /// <summary> /// 具體產品類: 越野車 /// </summary> public class JeepCar : ICar { public void GetCar() { Console.WriteLine("場務把越野車交給范·迪塞爾"); } } /// <summary> /// 具體產品類: 兩箱車 /// </summary> public class HatchbackCar : ICar { public void GetCar() { Console.WriteLine("場務把兩箱車交給范·迪塞爾"); } }}
客戶端代碼:
//------------------------------------------------------------------------------// <copyright file="Program.cs" company="CNBlogs Corporation">// Copyright (C) 2015-2016 All Rights Reserved// 原博文地址: http://www.49028c.com/toutou/// 作 者: 請叫我頭頭哥// </copyright> //------------------------------------------------------------------------------namespace CNBlogs.DesignPattern{ using System.IO; using System.Configuration; using System.Reflection; using CNBlogs.DesignPattern.Common; class Program { static void Main(string[] args) { // 工廠類的類名寫在配置文件中可以方便以后修改 string factoryType = ConfigurationManager.AppSettings["FactoryType"]; // 這里把DLL配置在數據庫是因為以后數據可能發生改變 // 比如說現在的數據是從sql server取的,以后需要從Oracle取的話只需要添加一個訪問oracle數據庫的工程就行了 string dllName = ConfigurationManager.AppSettings["DllName"]; // 利用.NET提供的反射可以根據類名來創建它的實例,非常方便 var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly(); string codeBase = currentAssembly.CodeBase.ToLower().Replace(currentAssembly.ManifestModule.Name.ToLower(), string.Empty); IFactory factory = Assembly.LoadFrom(Path.Combine(codeBase, dllName)).CreateInstance(factoryType) as IFactory; ICar car = factory.CreateCar(); car.GetCar(); } }}
7.工廠方法的優點/缺點:
1.介紹:
2.定義:
3.模擬場景:
4.場景分析:
上面的場景可能有點稀里糊涂的,但是用OO的思想結合前面的簡單工廠和工廠方法的思路去理解的話,也好理解。
下面讓我們來捋一捋這個思路:
5.抽象工廠UML類圖: (UML圖是我用windows自帶的paint手工畫的,所以可能不是很專業)
6.代碼演示:
抽象工廠代碼:
namespace CNBlogs.DesignPattern.Common{ /// <summary> /// 抽象工廠類 /// </summary> public abstract class AbstractEquipment { /// <summary> /// 抽象方法: 創建一輛車 /// </summary> /// <returns></returns> public abstract AbstractCar CreateCar(); /// <summary> /// 抽象方法: 創建背包 /// </summary> /// <returns></returns> public abstract AbstractBackpack CreateBackpack(); }}
抽象產品代碼:
namespace CNBlogs.DesignPattern.Common{ /// <summary> /// 抽象產品: 車抽象類 /// </summary> public abstract class AbstractCar { /// <summary> /// 車的類型屬性 /// </summary> public abstract string Type { get; } /// <summary> /// 車的顏色屬性 /// </summary> public abstract string Color { get; } } /// <summary> /// 抽象產品: 背包抽象類 /// </summary> public abstract class AbstractBackpack { /// <summary> /// 包的類型屬性 /// </summary> public abstract string Type { get; } /// <summary> /// 包的顏色屬性 /// </summary> public abstract string Color { get; } }}
具體工廠代碼:
namespace CNBlogs.DesignPattern.Common{ /// <summary> /// 運動裝備 /// </summary> public class SportEquipment : AbstractEquipment { public override AbstractCar CreateCar() { return new SportCar(); } public override AbstractBackpack CreateBackpack() { return new SportBackpack(); } } /// <summary> /// 越野裝備 這里就不添加了,同運動裝備一個原理,demo里只演示一個,實際項目中可以按需添加 /// </summary> //public class JeepEquipment : AbstractEquipment //{ // public override AbstractCar CreateCar() // { // return new JeeptCar(); // } // public override AbstractBackpack CreateBackpack() // { // return new JeepBackpack(); // } //}}
具體產品代碼:
namespace CNBlogs.DesignPattern.Common{ /// <summary> /// 跑車 /// </summary> public class SportCar : AbstractCar { private string type = "Sport"; private string color = "Red"; /// <summary> /// 重寫基類的Type屬性 /// </summary> public override string Type { get { return type; } } /// <summary> /// 重寫基類的Color屬性 /// </summary> public override string Color { get { return color; } } } /// <summary> /// 運動背包 /// </summary> public class SportBackpack : AbstractBackpack { private string type = "Sport"; private string color = "Red"; /// <summary> /// 重寫基類的Type屬性 /// </summary> public override string Type { get { return type; } } /// <summary> /// 重寫基類的Color屬性 /// </summary> public override string Color { get { return color; } } }}//具體產品可以有很多很多, 至于越野類的具體產品這里就不列出來了。
創建裝備代碼:
namespace CNBlogs.DesignPattern.Common{ public class CreateEquipment { private AbstractCar fanCar; private AbstractBackpack fanBackpack; public CreateEquipment(AbstractEquipment equipment) { fanCar = equipment.CreateCar(); fanBackpack = equipment.CreateBackpack(); } public void ReadyEquipment() { Console.WriteLine(string.Format("老范背著{0}色{1}包開著{2}色{3}車。", fanBackpack.Color, fanBackpack.Type, fanCar.Color, fanCar.Type )); } }}
客戶端代碼:
//------------------------------------------------------------------------------// <copyright file="Program.cs" company="CNBlogs Corporation">// Copyright (C) 2015-2016 All Rights Reserved// 原博文地址: http://www.49028c.com/toutou/// 作 者: 請叫我頭頭哥// </copyright> //------------------------------------------------------------------------------namespace CNBlogs.DesignPattern{ using System; using System.Configuration; using System.Reflection; using CNBlogs.DesignPattern.Common; class Program { static void Main(string[] args) { // ***具體app.config配置如下*** // //<add key="assemblyName" value="CNBlogs.DesignPattern.Common"/> //<add key="nameSpaceName" value="CNBlogs.DesignPattern.Common"/> //<add key="typename" value="SportEquipment"/> // 創建一個工廠類的實例 string assemblyName = ConfigurationManager.AppSettings["assemblyName"]; string fullTypeName = string.Concat(ConfigurationManager.AppSettings["nameSpaceName"], ".", ConfigurationManager.AppSettings["typename"]); AbstractEquipment factory = (AbstractEquipment)Assembly.Load(assemblyName).CreateInstance(fullTypeName); CreateEquipment equipment = new CreateEquipment(factory); equipment.ReadyEquipment(); Console.Read(); } }}
抽象工廠模式符合了六大原則中的開閉原則、里氏代換原則、依賴倒轉原則等等
7.抽象工廠的優點/缺點:
這篇博文從晚上下班7點到家一直寫到現在,說了一晚上的工廠,也扯了一晚上的速度與激情,在本博文完結的最后,給大家來一張速度與激情的畫面精彩照。(ps:是不是覺得這種畫面再配上一曲DJ一瓶啤酒會更嗨?。抗?..)
我們使用設計模式目的無非只有三個:a)縮短開發時間;b)降低維護成本;c)在應用程序之間和內部輕松集成。具體什么時候使用何種設計模式還得因項目而異。之所以對設計模式舊調重彈只是希望這個博文能對自己的架構之路有所提升,同時如果能幫助到其他人那就更完美了。
作 者:請叫我頭頭哥
出 處:http://www.49028c.com/toutou/
關于作者:專注于微軟平臺的項目開發。如有問題或建議,請多多賜教!
版權聲明:本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
特此聲明:所有評論和私信都會在第一時間回復。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信我
聲援博主:如果您覺得文章對您有幫助,可以點擊文章右下角【推薦】一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!
新聞熱點
疑難解答