第一章 代码无错就是优吗?(简单工厂模式)
今天是设计模式的第一章由于工作比较忙所以一直想写点什么,但是还是没时间写。这篇的主题是代码无错可以运行就是优质代码吗?
首先要实现一个业务代码:有部门A,B,C,D 四个部门但是A部门的奖金是10%,B部门的是20%,C部门是30%,D部门的是40% 编写一段代码实现输入底薪后计算出最后薪水
class Program { static void Main(string[] args) { Console.WriteLine("请输入底薪:"); int a =Convert.ToInt32(Console.ReadLine()); Console.WriteLine("请输入部门:"); string b = Console.ReadLine(); string d = String.Empty; if (b == "a") { d = (a * 0.1 + a).ToString(); } if (b == "b") { d = (a * 0.2 + a).ToString(); } if (b == "c") { d = (a * 0.3 + a).ToString(); } if (b == "d") { d = (a * 0.4 + a).ToString(); } Console.WriteLine("您的薪水是:{0}RMB",d); Console.ReadKey(); } }
先看上面的代码,复制运行下看看。 没问题吧需求的业务功能都实现了。但是这样的代码真的好吗?
首先临界值的问题放在一边不说:
项目大了这样的命名自己都搞不清楚这个变量是什么用的了,就像是给软件埋了几个地雷,谁来改谁就踩了地雷了。那么来改改?
class Program { static void Main(string[] args) { Console.WriteLine("请输入底薪:"); int BasicSalary =Convert.ToInt32(Console.ReadLine()); Console.WriteLine("请输入部门:"); string Department = Console.ReadLine(); string Salary = String.Empty; switch (Department) { case "a" : Salary = (BasicSalary * 0.1 + BasicSalary).ToString(); break; case "b": Salary = (BasicSalary * 0.2 + BasicSalary).ToString(); break; case "c": Salary = (BasicSalary * 0.3 + BasicSalary).ToString(); break; case "d": Salary = (BasicSalary * 0.4 + BasicSalary).ToString(); break; default: break; } Console.WriteLine("您的薪水是:{0}RMB",Salary); Console.ReadKey(); } }
这样行了吗?修改了命名修改了用switch代替if减少判断次数。哈哈你看到下面还有篇幅就猜到还不行。
这样的代码没有面向对象复用性很差 解决的办法是业务的封装再来改改
class Program { static void Main(string[] args) { Console.WriteLine("请输入底薪:"); int BasicSalary = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("请输入部门:"); string Department = Console.ReadLine(); Console.WriteLine("您的薪水是:{0}RMB", GetResult(Department, BasicSalary)); Console.ReadKey(); } public static string GetResult(string _department, int _basicsalary) { string Salary = String.Empty; switch (_department) { case "a": Salary = (_basicsalary * 0.1 + _basicsalary).ToString(); break; case "b": Salary = (_basicsalary * 0.2 + _basicsalary).ToString(); break; case "c": Salary = (_basicsalary * 0.3 + _basicsalary).ToString(); break; case "d": Salary = (_basicsalary * 0.4 + _basicsalary).ToString(); break; default: break; } return Salary; } }
嗯改了下业务和视图分开 这样Web,手机程序等等都可以调用这样业务逻辑就不用再Ctrl+C,在Ctrl+V了而且到后期业务逻辑修改了也不用再一个一个副本去修改了,改一下GetResult函数就可以咯。
我们继续 哈哈 还有啊...
如果今天公司发展和业务的需要加了一个部门f 那代码就需要修改业务代码了 破坏了代码的封装性 那怎么处理才是不破话封装呢。那就是面向对象的其他2个特性多态和继承
请看下面的代码:
public class Operation { private int basicsalary; public int BasicSalary { get { return basicsalary; } set { basicsalary = value; } } public virtual string GetResult() { string Salary = String.Empty; return Salary; } } class OperationA : Operation { public override string GetResult() { string Salary = String.Empty; Salary = (BasicSalary * 0.1 + BasicSalary).ToString(); return Salary; } } class OperationB : Operation { public override string GetResult() { string Salary = String.Empty; Salary = (BasicSalary * 0.2 + BasicSalary).ToString(); return Salary; } } class OperationC : Operation { public override string GetResult() { string Salary = String.Empty; Salary = (BasicSalary * 0.3 + BasicSalary).ToString(); return Salary; } } class OperationD : Operation { public override string GetResult() { string Salary = String.Empty; Salary = (BasicSalary * 0.4 + BasicSalary).ToString(); return Salary; } } class Program { static void Main(string[] args) { Console.WriteLine("请输入底薪:"); int BasicSalary = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("请输入部门:"); string Department = Console.ReadLine(); Operation oper = OperationFactory.createOperate(Department); oper.BasicSalary = BasicSalary; Console.WriteLine("您的薪水是:{0}RMB", oper.GetResult()); Console.ReadKey(); } } public class OperationFactory { public static Operation createOperate(string operate) { Operation oper = null; switch (operate) { case "a": oper = new OperationA(); break; case "b": oper = new OperationB(); break; case "c": oper = new OperationC(); break; case "d": oper = new OperationD(); break; default: break; } return oper; } }
怎么样现在只要写一个运行对象然后加个new 就可以楼 不用去修改原来的业务逻辑噢。如果要修改界面就只要改界面的类楼。下面是UML图
吴蒋
2010.8.13