C#设计模式--简单工厂模式
简单工厂模式是属于创建型模式,但不属于23种GOF设计模式之一。
举一个例子:一个公司有不同的部门,客户根据需要打电话到不同的部门。客户相当于上端,不同部门相当于下端。不使用简单工厂模式来实现的例子如下:
#region 上端 class Program { static void Main(string[] args) { Console.WriteLine("********不使用工厂方法******"); HRDept hr = new HRDept(); hr.Call(); TechnologyDept technology = new TechnologyDept(); technology.Call(); Console.ReadKey(); } } #endregion #region 下端 class HRDept { public void Call() { Console.WriteLine("这是人事部"); } } class TechnologyDept { public void Call() { Console.WriteLine("这是技术部"); } } #endregion
从这个例子可以发现客户需要找一个部门,就必须知道那个部门的电话号码。即上端直接依赖于下端。 每回都需要去new一下,完全把下端类暴露给上端。并且下端改变,上端必须改变。而在我们的实际生活中,客户并不知道每个部门的具体号码,都是打电话到前台,让前台将电话转到对应部门。而前台就相当于一个简单工厂。HRDept类和TechnologyDept类都有Call()方法,所以可以定义一个接口,声明这个方法。
#region 上端 class Program { static void Main(string[] args) { Console.WriteLine("********工厂方法******"); IDept hr = SimpleFactory.CreateInstance("HR"); hr.Call(); IDept technology = SimpleFactory.CreateInstance("Technology"); technology.Call(); Console.ReadKey(); } } #endregion #region 下端 class SimpleFactory { public static IDept CreateInstance(string name) { switch (name) { case "HR": return new HRDept(); case "Technology": return new TechnologyDept(); default: throw new Exception("部门名称错误"); } } } interface IDept { void Call(); } class HRDept: IDept { public void Call() { Console.WriteLine("这是人事部"); } } class TechnologyDept: IDept { public void Call() { Console.WriteLine("这是技术部"); } } #endregion
由上可以发现简单工厂,创建一个工厂类,负责对象的创建,而不是在上端使用的地方直接创建。面向抽象,屏蔽细节。 缺陷:把对象创建转移到工厂,上端不关心细节,修改类的时候需要修改工厂方法。工厂方法自身高耦合,矛盾转移,将上端与下端的耦合转移到工厂方法,严重违背单一职责。
简单工厂:创建一个工厂类,负责对象的创建,而不是在上端使用的地方直接创建。
缺陷:把对象创建转移到工厂,上端不关心细节,修改类的时候需要修改工厂方法。工厂方法自身高耦合,矛盾转移,将上端与下端的耦合转移到工厂方法,严重违背单一职责。
工厂类完成对象的创建。在使用时只需要调用工厂类的CreateInstance()方法,通过传递不同参数,创建不同的类。
简单工厂的升级
1.简单工厂+配置文件
代码示例:
工厂类
class SimpleFactory { //简单工厂+配置文件 //添加引用System.Configuration.dll private static string RaceTypeConfig = ConfigurationManager.AppSettings["DeptConfig"]; public static IDept CreateInstanceConfig() { switch (RaceTypeConfig) { case "HR": return new HRDept(); case "Technology": return new TechnologyDept(); default: throw new Exception("部门名称错误"); } } }
配置文件
<appSettings> <add key="DeptConfig" value="HRDept"/> </appSettings>
2.简单工厂+配置文件+反射
代码示例:
工厂类
class SimpleFactory { //简单工厂+配置文件+反射 private static string RaceTypeReflect = ConfigurationManager.AppSettings["DeptReflect"]; public static IDept CreateInstanceReflect() { string assemblyName = RaceTypeReflect.Split(',')[0]; string typeName = RaceTypeReflect.Split(',')[1]; return (IDept)(Activator.CreateInstance(assemblyName, typeName).Unwrap()); } }
配置文件
<appSettings> <add key="DeptReflect" value="SimpleFactory,SimpleFactory.HRDept"/> </appSettings>