設計模式:簡單工廠、工廠方法、抽象工廠
簡單工廠
簡單工廠模式是屬於建立型模式,又叫做靜態工廠方法模式,但不屬於23種設計模式。簡單工廠模式是由一個工廠物件決定創建出哪一種產品類的例項,簡單工廠模式是工廠模式家族中最簡單實用的模式。
程式碼演示:
/// <summary> /// 抽象 功能 /// </summary> public interface ISqlHelper { void ExecuteSql(); } public enum SqlType { SqlServer = 0, MySql =1, Oracle = 2 } /// <summary> /// 具體實現 /// </summary> public class SqlServerHelper : ISqlHelper { public void ExecuteSql() { Console.WriteLine("SqlServer 執行成功!"); } } public class MySqlHelper : ISqlHelper { public void ExecuteSql() { Console.WriteLine("MySql 執行成功!"); } } public class OracleHelper : ISqlHelper { public void ExecuteSql() { Console.WriteLine("Oracle 執行成功!"); } } //簡單工廠的核心程式碼 public class FactoryCore { public ISqlHelper ExecuteSql(SqlType sqlType) { ISqlHelper iSqlHelper = null; switch (sqlType) { case SqlType.SqlServer: iSqlHelper = new SqlServerHelper(); break; case SqlType.MySql: iSqlHelper = new MySqlHelper(); break; case SqlType.Oracle: iSqlHelper = new OracleHelper(); break; default: throw new Exception("ExecuteSql -- 引數異常!"); } return iSqlHelper; } } static void Main(string[] args) { //呼叫 ISqlHelper sqlHelper; try { FactoryCore fatory = new FactoryCore(); sqlHelper = fatory.ExecuteSql(SqlType.SqlServer); sqlHelper.ExecuteSql(); Console.ReadKey(); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
簡單工廠模式能夠根據外界給定的資訊,決定究竟應該建立哪個具體類的物件。明確區分了各自的職責和權力,有利於整個軟體體系結構的優化。
但是,很明顯工廠類集中了所有例項的建立邏輯,容易違反GRASPR的高內聚的責任分配原則。
工廠方法
工廠方法模式又稱多型性工廠模式。在工廠方法模式中,核心的工廠類不再負責所有的產品的建立,而是將具體建立的工作交給子類去做。該核心類成為一個抽象工廠角色,僅負責給出具體工廠子類必須實現的介面,而不接觸某一個具體類應當被例項化這種細節。
程式碼演示:
/// <summary> /// 抽象功能 /// </summary> public interface ISqlHelper { void ExecuteSql(); } /// <summary> /// 抽象工廠 /// </summary> public interface IFactory { ISqlHelper CreateSqlHelper(); } /// <summary> /// 具體實現 /// </summary> public class SqlServerHelper : ISqlHelper { public void ExecuteSql() { Console.WriteLine("SqlServer 執行成功!"); } } public class MySqlHelper : ISqlHelper { public void ExecuteSql() { Console.WriteLine("MySql 執行成功!"); } } public class OracleHelper : ISqlHelper { public void ExecuteSql() { Console.WriteLine("Oracle 執行成功!"); } } /// <summary> /// 具體工廠 /// </summary> public class SqlServerFactory : IFactory { public ISqlHelper CreateSqlHelper() { return new SqlServerHelper(); } } public class MySqlFactory : IFactory { public ISqlHelper CreateSqlHelper() { return new MySqlHelper(); } } public class OracleFactory : IFactory { public ISqlHelper CreateSqlHelper() { return new OracleHelper(); } } internal class Program { static void Main(string[] args) { IFactory iFactory = new SqlServerFactory(); ISqlHelper iSqlHelper = iFactory.CreateSqlHelper(); iSqlHelper.ExecuteSql(); /* * 可以把工廠類名和dll名 放到配置檔案中,然後利用反射來建立例項。 * 這樣就實現了程式的可配置性。 * * string factoryType = ConfigurationManager.AppSettings["FactoryType"]; * string dllName = ConfigurationManager.AppSettings["DllName"]; * var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly(); * string codeBase = currentAssembly.CodeBase.ToLower().Replace(currentAssembly.ManifestModule.Name.ToLower(), string.Empty); * IFactory iFactory = Assembly.LoadFrom(Path.Combine(codeBase, dllName)).CreateInstance(factoryType) as IFactory; * ISqlHelper iSqlHelper = iFactory.CreateSqlHelper(); * iSqlHelper.ExecuteSql(); * */ Console.ReadKey(); } }
工廠方法通過子類提供掛鉤。基類為工廠方法提供預設實現,子類可以重寫新的實現,也可以繼承父類的實現。 加一層間接性,增加了靈活性
遮蔽產品類。產品類的實現如何變化,呼叫者都不需要關心,只需關心產品的介面,只要介面保持不變,系統中的上層模組就不會發生變化。
典型的解耦框架。高層模組只需要知道產品的抽象類,其他的實現類都不需要關心,符合迪米特法則,符合依賴倒置原則,符合里氏替換原則。
多型性:客戶程式碼可以做到與特定應用無關,適用於任何實體類。
抽象工廠
抽象工廠模式是所有形態的工廠模式中最為抽象和最具一般性的一種形態。抽象工廠模式是指當有多個抽象角色時,使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個介面,使客戶端在不必指定產品的具體的情況下,建立多個產品族中的產品物件。根據里氏替換原則,任何接受父型別的地方,都應當能夠接受子型別。因此,實際上系統所需要的,僅僅是型別與這些抽象產品角色相同的一些例項,而不是這些抽象產品的例項。換言之,也就是這些抽象產品的具體子類的例項。工廠類負責建立抽象產品的具體子類的例項。
程式碼演示:
//抽象的產品 1 public interface IMobile { void Show(); } public interface INotebook { void Show(); } //抽象工廠 2 public interface IAbstractFactory { IMobile CtreateMobile(); INotebook CreateNotebook(); } //具體的產品 3 public class HuWeiMobile:IMobile { public void Show() { Console.WriteLine("華為手機!"); } } public class HuWeiNotebook : INotebook { public void Show() { Console.WriteLine("華為筆記本!"); } } public class AppleMobile : IMobile { public void Show() { Console.WriteLine("蘋果手機!"); } } public class AppleNotebook : INotebook { public void Show() { Console.WriteLine("蘋果筆記本!"); } } //具體工廠 4 public class HuWeiFactory:IAbstractFactory { public IMobile CtreateMobile() { return new HuWeiMobile(); } public INotebook CreateNotebook() { return new HuWeiNotebook(); } } public class AppleFactory : IAbstractFactory { public IMobile CtreateMobile() { return new AppleMobile(); } public INotebook CreateNotebook() { return new AppleNotebook(); } } internal class Program { static void Main(string[] args) { //呼叫 5 IAbstractFactory abstractFactory = null; abstractFactory = new HuWeiFactory(); IMobile mobile = abstractFactory.CtreateMobile(); INotebook notebook = abstractFactory.CreateNotebook(); mobile.Show(); notebook.Show(); Console.ReadKey(); } }
抽象工廠模式隔離了具體類的生產,使得客戶並不需要知道什麼被建立。
當一個產品族中的多個物件被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的物件。增加新的具體工廠和產品族很方便,無須修改已有系統,符合“開閉原則”。
但是,增加新的產品等級結構很麻煩!!!因為需要對原有系統進行較大的修改,甚至需要修改抽象層程式碼,這必然會帶來較大的不便,在這個角度,它違背了開閉(對擴充套件開放,對修改封閉)原則。