设计模式——简单工厂模式[已了解本质]
简单工厂模式多用于工厂本身包含了所有的运算方式,并且改动不大的情况。 例如我们现在使用的计算器,就那几种运算方式,所以很适合使用简单工厂模式,本文的计算器只列举加减乘除这四种运算方式。
本文参考了程杰的《大话设计模式》,使用C#语言利用面向对象的模式来写一个计算器。
如果是我本人来写计算器,也就加减乘除的话,估计我会全部写进控制台里面,写4个if语句出来......或者我会利用switch,但是这样的效果都不好,有更好的方法,就是如下所示的代码啦:
先定义一个Operation类,主要实现运算框架:
class Operation { public double Number1 { get; set;} public double Number2 { get; set; } public virtual double GetResult() //虚方法 { double result=0; return result; } }
接下来是运算的类啦,这里我们先写加减乘除这四种操作吧:
class OperationAdd:Operation { public override double GetResult() { double result = 0; result = Number1 + Number2; return result; } }
class OperationSub:Operation { public override double GetResult() { double result = 0; result = Number1 - Number2; return result; } }
class OperationMul:Operation { public override double GetResult() { double result = 0; result = Number1 * Number2; return result; } }
class OperationDiv:Operation { public override double GetResult() { double result = 0; if (Number2==0) { throw new Exception("除数不能为0"); } result = Number1 * Number2; return result; } }
然后再控制台我们要调用这些运算逻辑方法对不,怎么调用呢?这里再写一个简单工厂模式来选择:
class OpertionFactory { public static Operation createOperation(string Operate) { Operation oper = null; switch (Operate) { case "+": oper = new OperationAdd(); break; case "-": oper = new OperationSub(); break; case "*": oper = new OperationMul(); break; case "/": oper = new OperationDiv(); break; } return oper; } }
这个简单工厂模式就是为了选择运算逻辑而存在的。
最后,我们在控制台来实现一下吧:
class Program { static void Main(string[] args) { Operation oper; oper = OpertionFactory.createOperation("+"); //我这里写死了,就是测试一下 oper.Number1 = 1; oper.Number2 = 0; double result = oper.GetResult(); Console.WriteLine(result); Console.ReadLine(); } }
这样,一个计算器的代码就写完了,相比于4个if语句或者是switch语句,这种方式要好很多,如果要添加新的运算,例如开平方,求余运算等等...我都可以添加一个相应的逻辑运算,然后在简单工厂模式的OperationFactory类里面添加分支就好了。不会影响其他的逻辑运算代码,后台与前台代码也是分开的。但是!这种简单工厂模式也存在着缺点,就是一旦有了新的需求就要修改OperationFactory类,不利于维护和扩展。所以明白了文章首句加黄色显示的那句话的意思了吧~~
要解决这个缺点需要用到反射的知识,好像有一句话叫:反射 反射 程序员的快乐~
简单工厂模式,真正的表演开始了。
简单工厂模式多用于工厂本身包含了所有的运算方式,并且改动不大的情况。
上面的看看就得了,工厂那里,我们写的switch,写死的,太Low了,我新加一种算法,比如平方,我还要改工厂类的代码???
讲讲我的理解,所谓的简单工厂模式,必须是工厂使用的方法,最好是固定的,比如工厂是超市,那么我规定,超市就只有两个方法,进货和卖货。又比如说是计算器,我规定,计算器只有一个方法,就是计算。
这种情况下,简单工厂模式才开始发挥威力了。修改过后的工厂代码和调用的主方法如下,我使用了C#来介绍,其实Java也很简单。
简单工厂的代码,通过反射获取实例
using System; namespace NetCore { public class OpertionFactory { public static Operation createOperation (string Operate) { Type type = Type.GetType(typeof (Operation).Namespace + "." + Operate); return (Operation) Activator.CreateInstance (type); } } }
我的主方法
using System; namespace NetCore { class Program { static void Main (string[] args) { Operation a = OpertionFactory.createOperation ("OperationSub"); a.Number1 = 1; a.Number2 = 2; System.Console.WriteLine (a.GetResult ()); } } }
这就是精髓之处了,我通过输入算法名,通过工厂反射得到算法实例,然后自己去算。这样一来,就算我加入新的算法,只需要写个继承运算类的算法类,然后主方法调用即可。工厂根本不需要动。自己就反射了
要是还用上面的工厂写switch,垃圾啊,我还得改switch,所以简单工厂模式的核心就是,反射。
反射,反射,程序员的快乐