一、基本概念
众所周知,C#是一种面向对象的语言,而其中封装,继承,多态是面向对象的三大重要特征,简单工厂的设计模式则可以完全体现这些特征。要彻底理解这个模式,必须要先将封装(访问修饰符的应用)、继承(基类和派生类的概念)、多态(重载,虚方法,重写,抽象方法的概念)全部搞懂,并能灵活运用。
1.简单工厂模式定义
简单工厂模式简单来说就是创建一个工厂类,通过输入的参数创建对象赋值给基类,完成对想要的派生类的调用,从而达成目标,具体的操作均在子类中完成,工厂类只负责运算逻辑和给基类赋值。该模式有三部分:
1、工厂类:实现创建所有实例的选择类型,被外界调用的接口。
2、抽象类:所要创建的类的基类,描述类所有实例所共有的公共接口(方法),可以是抽象类也可是接口类型(interface),本例是抽象类。
3、具体类:所有要创建的具体实例对象。
为什么要用简单工厂模式来做呢?按照我的理解,原因如下:
通常需要面对的对象会有很多,这就会有很多类产生,而要调用类的对象需要对类进行实例化,大家想一下,如果每个类都在主函数内进行实例化,那需要写很多的代码,所以需要通过多态的方法来实现,另外通过工厂类的方法完成对子类对象的实例化,也就是给基类赋值,从而调用子类方法。
二、举例
比如去吃饭的时候,你想问某个饭还有多长时间做好,还想了解下菜谱,可供选择的类型有很多,像黄焖鸡米饭,河南烩面,饺子等等,那如果想“随便”喊一个饭的名称就能得到回答,就需要通过工厂模式实现。
首先,要先创建一个抽象类,将所有的饭的类型统称为"Food",类里面创建一个或多个抽象方法。注意,如果基类为抽象类,子类必须重写,这也是为什么创建抽象基类的原因,可以任意在子类方法里上面实现想要的效果。
public abstract class Food{public abstract void Ask();public abstract void Menu();}
然后,创建所有的子类,具体到每个饭。
public class Rice : Food{public override void Ask(){Console.WriteLine("黄焖鸡米饭正在制作中,还需1分钟");}public override void Menu(){Console.WriteLine("鸡,米,油,盐,酱油,海带丝,香菇,辣椒");}}public class Noodles: Food{public override void Ask(){Console.WriteLine("河南烩面正在制作中,还需1小时");}public override void Menu(){Console.WriteLine("面,羊肉汤,葱花,盐");}}public class Dumplings : Food{public override void Ask(){Console.WriteLine("饺子正在制作中,还需1天");}public override void Menu(){Console.WriteLine("韭菜,鸡蛋,油,盐");}}
然后,核心的部分来了,创建工厂类要实施的方法,其格式为:访问修饰符+静态关键字+基类名+方法名(参数名),这样就可以实现子类给基类赋值的功能。
//简单工厂的核心,根据用户的输入创建对象赋值给父类public static class 老高饭庄{public static Food Cook(string Foodname){Food f = null;switch (Foodname){case "黄焖鸡米饭":f = new Rice();break;case "河南烩面":f = new Noodles();break;case "韭菜鸡蛋饺子":f = new Dumplings();break;default:break;}return f;}}
最后,在主函数中对工厂类实例化,我们可以看到,通过工厂类可以实现对任意子类的调用。
static void Main(string[] args){Console.WriteLine("请输入菜名:");string Foodname = Console.ReadLine();Food f = 老高饭庄.Cook(Foodname);f.Ask();f.Menu();Console.ReadKey();}
程序显示
三、总结
这种模式的优点在于可以只通过参数即可完成对任意子类对象的调用,而且便于扩展。缺点也很明显,如果要增加一个类,那我必须要更改工厂类才能完成,违反开闭原则(一个软件实体应当对扩展开放,对修改封闭)。
先这样写,后面持续更新。