前面我们用面向对象的思想简单的实现了计算器。见http://www.cnblogs.com/wesley168/p/6226747.html。其实这里还是有其他问题的。
比如:现在我要除了要实现加减乘除外,还要添加其他运算,就需要修改switch中的代码。这违背了开闭原则(对修改关闭,对扩展开放)。
我们每次操作计算器的时候,都会输入两个数字,选择一个运算符,这是反复出现的。所以我们把输入的两个数字,运算符封装到一个类中,该类只实现一种运算。
由于每个类都要有两个数字,并且有个计算方法,但是这个方法在使用前并不知道里面是如何实现。所以我们把这个类设计成抽象类,里面的计算方法设计成抽象方法。代码如下:
1 public abstract class Calc 2 { 3 public int Number1 { get; set; } 4 5 public int Number2 { get; set; } 6 public Calc(int n1,int n2) 7 { 8 this.Number1 = n1; 9 this.Number2 = n2; 10 } 11 12 public abstract double Calculate(); 13 }
控制台中的代码如下:
1 static void Main(string[] args) 2 { 3 while (true) 4 { 5 Console.Write("请输入第一个数字: "); 6 int n1 = Convert.ToInt32(Console.ReadLine()); 7 8 Console.Write("请输入运算符: "); 9 string sign = Console.ReadLine(); 10 11 Console.Write("请输入第二个数字:"); 12 int n2 = Convert.ToInt32(Console.ReadLine()); 13 14 Calc c = GetCalcResult(n1, sign, n2); 15 16 Console.WriteLine("结果是:{0}", c.Calculate()); 17 18 } 19 20 //Console.ReadKey(); 21 }
这里进一步把switch中的代码封装成了一个简单工厂的核心方法。如果需要添加运算操作,可以直接添加每个运算对应的类,如:
加法:
1 public class Add : Calc 2 { 3 public Add(int n1, int n2) : base(n1, n2) 4 { 5 } 6 7 public override double Calculate() 8 { 9 return this.Number1 + this.Number2; 10 } 11 }
减法:
1 public class Sub : Calc 2 { 3 public Sub(int n1, int n2) : base(n1, n2) 4 { 5 } 6 7 public override double Calculate() 8 { 9 return this.Number1 - this.Number2; 10 } 11 }
乘法:
1 public class Mul : Calc 2 { 3 public Mul(int n1, int n2) : base(n1, n2) 4 { 5 } 6 7 public override double Calculate() 8 { 9 return this.Number1 * this.Number2; 10 } 11 }
除法:
1 public class Div : Calc 2 { 3 public Div(int n1, int n2) : base(n1, n2) 4 { 5 } 6 7 public override double Calculate() 8 { 9 throw new NotImplementedException(); 10 } 11 }
可能有人会问了,如果再添加新的运算符,还是需要更改switch中的方法。这里可以使用反射进一步优化。具体后面会进一步讲解。