这是重读《设计模式》一书的读书笔记第二篇,主要探讨工厂模式(Factory)
有几个重点
- 为什么需要工厂模式呢?工厂模式要解决的问题是创建对象实例的多变性,一个典型的例子就是假设我们的应用程序要既能够使用SQL Server作为数据库,也需要支持使用Oracle作为数据库(当然还可能会有其他的数据库),那么如何在不修改应用程序的情况下,能让它自动适用多种数据源呢?答案就是工厂模式。
- 工厂模式其实无处不在,而且即便我们自己以前没有写过,但至少都用到过了。在.NET框架中,很多地方都有工厂模式的影子。
- 工厂模式的核心是面向接口的编程。
- 工厂模式的另外一个核心是动态加载类型,也就是通过反射动态加载某个类型的实例。
- 工厂模式有两个具体的子模式
- 工厂方法模式(Factory Method) ——应用得更加多一些
- 抽象工厂模式(可以理解为更加复杂一些的场景)——Abastract Factory
下面有一个简单的实例(工厂方法模式:Factory Method)
using System; using System.Collections.Generic; using System.Reflection; namespace DesignPatternSample_Factory { class Program { static void Main(string[] args) { Console.WriteLine("使用SQL Server的数据访问组件"); IDAL dal = Factory.GetDALInstance("DesignPatternSample_Factory.SQLServerDAL"); foreach (var item in dal.GetEmployee()) { Console.WriteLine(item); } Console.WriteLine(); Console.WriteLine("使用Oracle的数据访问组件"); dal = Factory.GetDALInstance("DesignPatternSample_Factory.OracleDAL"); foreach (var item in dal.GetEmployee()) { Console.WriteLine(item); } Console.Read(); } } //第一步:定义接口 /// <summary> /// 定义一个数据访问层的接口,要求所有数据访问层都实现该接口 /// </summary> interface IDAL { List<string> GetEmployee(); } //第二步:定义工厂 class Factory { public static IDAL GetDALInstance(string typeName) { return Assembly.GetExecutingAssembly().CreateInstance(typeName) as IDAL; } } //第三步:具体实现DAL class SQLServerDAL : IDAL { #region IDAL 成员 public List<string> GetEmployee() { return new List<string>(new[] { "John", "Mike" }); } #endregion } class OracleDAL : IDAL { #region IDAL 成员 public List<string> GetEmployee() { return new List<string>(new[] { "Roy", "Rebecca" }); } #endregion } }
下面再来看一个抽象工厂的模式实现的代码例子,从代码中可以看出,如果工厂需要做一系列的动态化工作,那么可以考虑抽象工厂模式。
using System; using System.Configuration; using System.Reflection; namespace DesignPattern_Factory_AbstractFactorySample { class Program { static void Main(string[] args) { var factoryType = ConfigurationManager.AppSettings["FactoryType"]; var factory = Assembly.GetExecutingAssembly().CreateInstance(factoryType) as Factory; var profile = factory.GetProfileDALInstance(); var business = factory.GetBusinessDALInstance(); profile.Load("Test"); profile.Save(); business.CreateOrder(1, DateTime.Now, 1); } } #region 接口定义和抽象工厂定义 interface IProfileDAL { void Save(); object Load(string key); } interface IBusinessDAL { int CreateOrder(int orderID, DateTime time, int employeeId); } abstract class Factory { public abstract IProfileDAL GetProfileDALInstance(); public abstract IBusinessDAL GetBusinessDALInstance(); } #endregion #region 一套简单的工厂及其实现 class SimpleFactory : Factory { public override IProfileDAL GetProfileDALInstance() { return new SimpleProfileDAL(); } public override IBusinessDAL GetBusinessDALInstance() { return new SimpleBusinessDAL(); } } class SimpleProfileDAL : IProfileDAL { #region IProfileDAL 成员 public void Save() { } public object Load(string key) { return this.GetType(); } #endregion } class SimpleBusinessDAL : IBusinessDAL { #region IBusinessDAL 成员 public int CreateOrder(int orderID, DateTime time, int employeeId) { return 0; } #endregion } #endregion #region 一套复杂的工厂及其实现 class ComplexFactory : Factory { public override IProfileDAL GetProfileDALInstance() { return new ComplexProfileDAL(); } public override IBusinessDAL GetBusinessDALInstance() { return new ComplexBusinessDAL(); } } class ComplexProfileDAL : IProfileDAL { #region IProfileDAL 成员 public void Save() { throw new NotImplementedException(); } public object Load(string key) { throw new NotImplementedException(); } #endregion } class ComplexBusinessDAL : IBusinessDAL { #region IBusinessDAL 成员 public int CreateOrder(int orderID, DateTime time, int employeeId) { throw new NotImplementedException(); } #endregion } #endregion }