在介绍简单工厂模式之间,我们首先得清楚面向对象的三大特性:封装、继承、多态。
封装:
每个对象都包括自己进行操作所需要的所有信息,而不依赖于其他对象来完成自己的操作。这样的方法和属性通过类的实例来实现。
通过良好的封装可以降低耦合度;类的内部可以自由修改;类具有对外的清晰接口。
继承:通过对对象进行抽象父类,子类实现父类功能并可扩展。
1.子类拥有父类非private的属性和功能(父类的构造函数例外,可以用base关键字访问,base代表着父类);
2.子类具有自己的属性和功能,即子类可以扩展父类没有的属性和功能;
3.子类可以以自己的方式重写父类的功能。
缺点:父类变,子类不得不变,父子是一种强耦合的关系。
多态:不同的对象可以执行相同的动作。
1.子类以父类的身份出现;
2.子类在运行时以自己的方式实现;
3.子类以父类的身份出现时,子类特有的属性和方法不可以使用。
为了使子类的实例完全接替来自父类的类成员,父类必须将该成员声明为虚拟的(virtual),子类可以选择使用override将父类的实现替换为自己的实现,这就是多态。
原理:当方法被调用时,无论是否转换为其父类,都只有位于对象继承链最末端的方法实现会被调用。即,虚方法是按照运行时类型而非编译时类型进行动态绑定调用的。
简单工厂模式就是充分利用了面向对象的三大特性,将实例化对象的过程分离出来创建一个类或者是项目。
以实现计算器为例:
计算器,顾名思义主要功能就是计算,要实现计算,两个因素必不可少:输入参数和实现方法。所以我们定义一个运算类,包含这两个属性和方法:
1 /// <summary> 2 /// 运算类 3 /// </summary> 4 public class Operation 5 { 6 private double _numberA = 0; 7 private double _numberB = 0; 8 9 /// <summary> 10 /// 数字A 11 /// </summary> 12 public double NumberA 13 { 14 get 15 { 16 return _numberA; 17 } 18 set 19 { 20 _numberA = value; 21 } 22 } 23 24 /// <summary> 25 /// 数字B 26 /// </summary> 27 public double NumberB 28 { 29 get 30 { 31 return _numberB; 32 } 33 set 34 { 35 _numberB = value; 36 } 37 } 38 39 /// <summary> 40 /// 得到运算结果 41 /// </summary> 42 /// <returns></returns> 43 public virtual double getResult() 44 { 45 double result = 0; 46 return result; 47 } 48 49 50 }
上面的运算类其实就是一个运算方法的抽象,包含了运算的所有元素,下面我们可以针对特定的运算方法进行扩展,如加法:
1 /// <summary> 2 /// 加法类 3 /// </summary> 4 class OperationAdd : Operation 5 { 6 public override double getResult() 7 { 8 double result = 0; 9 result = NumberA + NumberB; 10 return result; 11 } 12 }
当然你也可以扩展其他的操作方法。现在有了实现各种运算的类对象,那我们该什么时候实例化何种运算类呢?下面我们就要用到一个工厂类:
1 /// <summary> 2 /// 运算类工厂 3 /// </summary> 4 class OperationFactory 5 { 6 public static Operation createOperate(string operate) 7 { 8 Operation oper = null; 9 switch (operate) 10 { 11 case "+": 12 { 13 oper = new OperationAdd(); 14 break; 15 } 16 case "-": 17 { 18 oper = new OperationSub(); 19 break; 20 } 21 case "*": 22 { 23 oper = new OperationMul(); 24 break; 25 } 26 case "/": 27 { 28 oper = new OperationDiv(); 29 break; 30 } 31 case "sqr": 32 { 33 oper = new OperationSqr(); 34 break; 35 } 36 case "sqrt": 37 { 38 oper = new OperationSqrt(); 39 break; 40 } 41 case "+/-": 42 { 43 oper = new OperationReverse(); 44 break; 45 } 46 } 47 48 return oper; 49 } 50 }
创建了运算工厂类,在进行运算的时候,我们只需要实例化运算类,然后对实例赋值运算值,调用运算工厂确定运算操作:
1 Operation oper; 2 oper = OperationFactory.createOperate(strOperate); 3 oper.NumberA = Convert.ToDouble(strNumberA); 4 oper.NumberB = Convert.ToDouble(strNumberB); 5 strResult = oper.GetResult().ToString();