今天学了点设计模式,虽然只是最基本的,或许根本算不上设计模式,但想想还是记下来,梳理一下,以后回头也可以看看。
看的是《大话设计模式》这本书,所以代码也基本跟书中一样。
首先,让我们写个简单的计算器,对两个数字进行运算。
如果是以前面向过程的思维,那么我会在main函数中直接用if-else语句判断符号,然后进行计算出结果。
后来如果用面向对象的思维,那么我会写一个运算类,然后用switch语句,把加减乘除都封装起来,在main函数中调用。
如今,让我们结合封装,继承,多态,用一下简单工厂模式
其实,为了降低程序的耦合性,我们要把各种运算都分离出来。
运算类可以抽象成为一个父类,而基本的加减乘除都是它的子类。
public class Operation { private double numA = 0; public double NumA { get { return numA; } set { numA = value; } } private double numB = 0; public double NumB { get { return numB; } set { numB = value; } } public virtual double getResult() { double result = 0; return result; } }
子类:
class Add : Operation { public override double getResult() { double result = 0; result = NumA + NumB; return result; } } class Sub:Operation { public override double getResult() { double result = 0; result = NumA - NumB; return result; } } class Mul:Operation { public override double getResult() { double result = 0; result = NumA * NumB; return result; } } class Div:Operation { public override double getResult() { double result = 0; if (NumB == 0) { throw new Exception("除数不能为0!"); } else { result = NumA / NumB; return result; } } }
那么如何去实例化各个对象呢,这就需要一个工厂类了。
这个工厂里我们通过多态实例化想对应的对象,然后返回这个对象。
public class NumFactory { public static Operation create(String operate) { Operation oper = null; switch (operate) { case "+": oper = new Add(); break; case "-": oper = new Sub(); break; case "*": oper = new Mul(); break; case "/": oper = new Div(); break; } return oper; } }
这样的话,在客户端代码中就能通过工厂类产生适合的对象并进行操作。
//不考虑过多的容错代码 public class Program { public static bool judge(String tmp) { if (!tmp.Equals("+") && !tmp.Equals("-") && !tmp.Equals("*") && !tmp.Equals("/") return false; else return true; } public static void Main(string[] args) { try { Operation oper = new Operation(); String tmp = Console.ReadLine(); //先输入运算符号,再输入两个数字 if (!judge(tmp)) { throw new Exception("运算符号不正确!"); } oper = NumFactory.create(tmp); oper.NumA = Convert.ToDouble(Console.ReadLine()); oper.NumB = Convert.ToDouble(Console.ReadLine()); Console.WriteLine(oper.getResult()); } catch (Exception e) { Console.WriteLine(e.Message); } } }
这样就算完成了,可以看到,该程序的可维护性,以及可扩展性已得到了提高。
如果要加入一种新的运算,只需增加一个运算子类,然后在工厂中做对应的修改即可。
简单工厂方法将初始化的工作放到了工厂类中,“动态”地生产产品。
这样客户类就只需提供参数,而对象如何创建,也就与客户类无关了。