来自:CCNetCore社区,一个关注.Netcore领域的社区团队。
创建对象交由工厂的方法完成,通过枚举switch来进行判断创建什么对象。
在一个简单工厂类中会实例化多个具体对象,其实也进行了高度耦合。
那么创建对象可有以下方式:
枚举,switch判断直接new实例化
从配置文件中获取字符串,通过反射进行实例化对象
注意:该简单工厂方法并未被23种GOF收录
using FactoryPattern.War3.Interface; using FactoryPattern.War3.Service; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SimpleFactory { /// <summary> /// 1 依赖倒置原则,SimpleFactory /// 2 简单工厂+ 配置文件=可配置 /// 3 简单工厂+ 配置文件+反射=可配置可扩展 /// 4 简单工厂升级IOC控制反转 /// /// 备战2019跳槽季,设计模式再来一波 /// 设计模式:面向对象语言开发过程中,遇到种种的场景和问题,提出解决方案和思路,沉淀下来 /// 前辈的智慧,是解决问题的套路,学习设计模式就是为了站在前辈的肩膀上 /// 结构型设计模式(装饰器):关注类与类之间的关系 /// 行为型设计模式(责任链):关注对象和行为的分离 /// 创建型设计模式(三大工厂):关注对象的创建 /// 学习设计模式的套路: /// 场景出发---解决问题---沉淀总结---推广应用(无尽升级) /// /// 依赖倒置原则:上层模块不应该依赖于下层模块,二者应该通过抽象来依赖 /// 依赖抽象,而不是依赖细节 /// /// GOF23种设计模式是不包含简单工厂 /// 简单工厂设计模式:包含一组需要创建的对象,通过一个工厂类来实例化对象, /// 好处就是去掉上端对细节的依赖,保证上端的稳定 /// 缺陷: /// 没有消除矛盾,只是转移矛盾,甚至还集中了矛盾 /// 任何设计模式都是解决一类问题的,不是万能的, /// 通常在解决一类问题的时候,还会带来新的问题 /// </summary> class Program { static void Main(string[] args) { try { Player player = new Player() { Id = 123, Name = "Eleven" }; { Human race = new Human();//1 最原始最习惯的 } { IRace race = new Human();//2 左边换成抽象 依赖倒置原则 } { IRace race = ObjectFactory.CreateInstance(RaceType.Human); //new IRace();//接口不能直接实例化 问题出来了,既不想依赖细节,又需要对象 player.Play(race); } { //可配置 Console.WriteLine("*****************Factory+Config***************"); IRace race = ObjectFactory.CreateInstanceConfig(); player.Play(race); } { //可配置可扩展 Console.WriteLine("*****************Factory+Config+Reflection***************"); IRace race = ObjectFactory.CreateInstanceConfigReflection(); player.Play(race); } //{ // Human human = new Human(); // player.PlayHuman(human); // player.Play(human); //} //{ // Undead undead = new Undead(); // player.PlayUndead(undead); // player.Play(undead); //} //{ // ORC oRC = new ORC(); // player.Play(oRC); //} //{ // NE nE = new NE(); // player.Play(nE); //} //类库 } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.Read(); } } }
using FactoryPattern.War3.Interface; using FactoryPattern.War3.Service; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace SimpleFactory { /// <summary> /// /// </summary> public class ObjectFactory { public static IRace CreateInstance(RaceType raceType) { IRace race = null; switch (raceType) { case RaceType.Human: race = new Human(); break; case RaceType.NE: race = new NE(); break; case RaceType.ORC: race = new ORC(); break; case RaceType.Undead: race = new Undead(); break; default: throw new Exception("wrong raceType"); } return race; } private static string IRaceType = ConfigurationManager.AppSettings["IRaceType"]; public static IRace CreateInstanceConfig() { RaceType raceType = (RaceType)Enum.Parse(typeof(RaceType), IRaceType); return CreateInstance(raceType); } //真正的把细节依赖给去掉,意味着不能直接new,那怎么获取对象? 反射 private static string IRaceTypeReflection = ConfigurationManager.AppSettings["IRaceTypeReflection"]; public static IRace CreateInstanceConfigReflection() { Assembly assembly = Assembly.Load(IRaceTypeReflection.Split(',')[1]); Type type = assembly.GetType(IRaceTypeReflection.Split(',')[0]); return (IRace)Activator.CreateInstance(type); } //1 可配置后,如果一个接口,可能需要不同的实例? //2 今天只是创建Race,就需要一个方法;那项目中有N多个接口,难道每个接口都去创建一个工厂方法吗? //3 IOC&&DI。。。。 /* 今天课程都能听懂,100% 刷个1 80% 刷个2 低于80% 刷个3 后面的三个问题我也了解的 刷个4 */ } public enum RaceType { Human, NE, ORC, Undead } }
最后,想了解更多,可加入CCNetCore社区,橙子带你走上.netcore学习之路。
你可以免费获取到:
站点网址:ccnetcore.com