前段时间在网上看了小菜成长日记,它主要讲的是一个刚刚入行的初级程序员是如何一步步的把自己的程序面向对象的,应该说是真正面向对象的。
实事上,根据客户的一种需求,做出一个解决方案并不难,难的是如何在原版程序上,以改动更小,时间最快的实现客户的第二次,第三次,第N次
的改版工作,因为客户的程序不可能不会有任何变化,当你的程序研发出来后,客户在使用中更有新的需求,这是很正常的,也是软件行业里永远不
变的,对于一个程序开发者来说,不要对此进行抱怨,应该以一种积极的态度去面对它,事实上,在程序改版的过程中,你利用面向对象的设计方法,
在实现中运用它的设计原则及设计模型来解决实现中的问题,些不要为了原则而原则;不要为了模式去模式,只有这样,你的工作经验才会有所提高,
你的能力才会有所提高。
我们来看一个小菜同学设计的1.0版计算器:
1: #region 小菜的计算器
2: try
3: {
4: Console.Write("请输入数字A:");
5: string strNumberA = Console.ReadLine();
6: Console.Write("请选择运算符号(+、-、*、/):");
7: string strOperate = Console.ReadLine();
8: Console.Write("请输入数字B:");
9: string strNumberB = Console.ReadLine();
10: string strResult = "";
11: switch (strOperate)
12: {
13: case "+":
14: strResult = Convert.ToString(Convert.ToDouble(strNumberA) + Convert.ToDouble(strNumberB));
15: break;
16: case "-":
17: strResult = Convert.ToString(Convert.ToDouble(strNumberA) - Convert.ToDouble(strNumberB));
18: break;
19: case "*":
20: strResult = Convert.ToString(Convert.ToDouble(strNumberA) * Convert.ToDouble(strNumberB));
21: break;
22: case "/":
23: if (strNumberB != "0")
24: strResult = Convert.ToString(Convert.ToDouble(strNumberA) / Convert.ToDouble(strNumberB));
25: else
26: strResult = "除数不能为0";
27: break;
28: }
29: Console.WriteLine("结果是:" + strResult);
30: Console.ReadLine();
31: }
32: catch (Exception ex)
33: {
34: Console.WriteLine("您的输入有错:" + ex.Message);
35: }
36: #endregion
这段程序显然不是完全面向对象的,或者说,它还不能完全展现面向对象的特性,之后小菜同学把代码进行了修改:
1: #region 小菜的面向对象的计算器第二版(运用了封装,继承和多态及简单工厂模块,使业务与显示层分开,代码也得到了复用)
2: /// <summary>
3: /// 运算类
4: /// </summary>
5: public abstract class Operation
6: {
7: /// <summary>
8: /// 数字A
9: /// </summary>
10: public double NumberA
11: {
12: get;
13: set;
14: }
15: /// <summary>
16: /// 数字B
17: /// </summary>
18: public double NumberB
19: {
20: get;
21: set;
22: }
23: /// <summary>
24: /// 得到运算结果
25: /// </summary>
26: /// <returns></returns>
27: public virtual double GetResult()
28: {
29: double result = 0;
30: return result;
31: }
32: }
33: /// <summary>
34: /// 加法类
35: /// </summary>
36: public class OperationAdd : Operation
37: {
38: public override double GetResult()
39: {
40: double result = 0;
41: result = NumberA + NumberB;
42: return result;
43: }
44: }
45: /// <summary>
46: /// 减法类
47: /// </summary>
48: public class OperationSub : Operation
49: {
50: public override double GetResult()
51: {
52: double result = 0;
53: result = NumberA - NumberB;
54: return result;
55: }
56: }
57: /// <summary>
58: /// 乘法类
59: /// </summary>
60: public class OperationMul : Operation
61: {
62: public override double GetResult()
63: {
64: double result = 0;
65: result = NumberA * NumberB;
66: return result;
67: }
68: }
69: /// <summary>
70: /// 除法类
71: /// </summary>
72: public class OperationDiv : Operation
73: {
74: public override double GetResult()
75: {
76: double result = 0;
77: if (NumberB == 0)
78: throw new Exception("除数不能为0。");
79: result = NumberA / NumberB;
80: return result;
81: }
82: }
83:
84: /// <summary>
85: /// 运算类工厂
86: /// </summary>
87: public class OperationFactory
88: {
89: public static Operation createOperate(string operate)
90: {
91: Operation oper = null;
92: switch (operate)
93: {
94: case "+":
95: {
96: oper = new OperationAdd();
97: break;
98: }
99: case "-":
100: {
101: oper = new OperationSub();
102: break;
103: }
104: case "*":
105: {
106: oper = new OperationMul();
107: break;
108: }
109: case "/":
110: {
111: oper = new OperationDiv();
112: break;
113: }
114: }
115: return oper;
116: }
117: }
118: #endregion
这回,我们看到了面向对象的特性,它的代码可以被复用,即它可以为WEB,WINFORM或CONSOLE程序复用,而且我们也看到了面向对象的多态性,代码比版本一
的耦合度降低了,它的加,减,乘,除完全独立出来,这样扩展也方便了,如果加一个平方或开方运算,我们只要加一个子类去实现基类就可以了。
好了,今天就讲到这吧