本宝宝只是一个菜鸟,写写学习笔记,以便温故知新,如果哪里不对或者不足,望大牛指正。
1.我们先举个例子说明一下,eg:加减乘除的运算[一步步优化]
ⅰ.[第一种写法]
class Program { static void Main(string[] args) { //第一种方法,显得不专业 //输入 Console.Write("请输入一个数字:"); //接收 string A = Console.ReadLine(); Console.Write("请输入运算符,+、-、*、/"); string B = Console.ReadLine(); Console.Write("请输入第二个数字"); string C = Console.ReadLine(); Console.Write("结果等于"); string D = ""; if (B == "+") { //string转换为double,不能忘记tostring() D = (Convert.ToDouble(A)+Convert.ToDouble(C)).ToString(); } if (B == "-") { D = (Convert.ToDouble(A) + Convert.ToDouble(C)).ToString(); } if (B == "*") { D=(Convert.ToDouble(A)+Convert.ToDouble(C).ToString()); } if (B == "/") { D=(Convert.ToDouble(A)+Convert.ToDouble(C).ToString()); } Console.WriteLine("结果是:"+D); } }
ⅱ.以上的这种写法,显得特别不专业,也不美观,那就优化一下,看看[第二种写法]
class Program { static void Main(string[] args) { //这是第二种方式 try { Console.WriteLine("请输入一个数字"); string sInum1 = Console.ReadLine(); Console.WriteLine("请输入运算符,+、-、*、/"); string Oper = Console.ReadLine(); Console.WriteLine("请输入第二个数字"); string sInum2 = Console.ReadLine(); string sResult = ""; switch (Oper) { case "+": sResult = (Convert.ToDouble(sInum1) + Convert.ToDouble(sInum2)).ToString(); break; case "-": sResult = (Convert.ToDouble(sInum1) + Convert.ToDouble(sInum2)).ToString(); break; case "*": sResult = (Convert.ToDouble(sInum1) + Convert.ToDouble(sInum2)).ToString(); break; case "/": if (sInum2 == "") { sResult = "被除数不能为0"; } else { sResult = (Convert.ToDouble(sInum1) + Convert.ToDouble(sInum2).ToString()); } break; } Console.WriteLine("结果为:" + sResult); } catch (Exception ex) { // Console.WriteLine(ex); Console.WriteLine("温馨提示,网站正在维修,请联系管理员"); } } }
ⅲ.以上写法是不是也有许多不足呢?
业务逻辑层和和客户端混合在一起,高耦合,关联性太强:1.不利于使用和扩展;2.不安全;
那就再优化一下,看看[第三种写法][创建一个operating类之后调用]
我们把业务逻辑层和客户端分开,就好比我们买个车子,只需知道它如何使用就好。
class Program { static void Main(string[] args) { try { Console.WriteLine("请输入第一个数:"); string sInum1 = Console.ReadLine(); Console.WriteLine("请输入运算符,+、-、*、/"); string sOper = Console.ReadLine(); Console.WriteLine("请输入第二个数:"); string sInum2 = Console.ReadLine(); string sResult = ""; sResult = (Operating.GetResult(Convert.ToDouble(sInum1),Convert.ToDouble(sInum2),sOper)).ToString(); Console.WriteLine("结果为:"+sResult); } catch (Exception ex) { Console.WriteLine("温馨提示,网站正在维修,请联系管理员"); } } }
我们把业务逻辑层和客户端分开,以下代码相当于车子最核心,最底层的东西。
class Operating { public static double GetResult(double iNum1, double iNum2, string sOper) { double Result = 0d; switch (sOper) { case "+": Result = iNum1 + iNum2; break; case"-": Result = iNum1 - iNum2; break; case"*": Result = iNum1 * iNum2; break; case"/": Result = iNum1 / iNum2; break; } return Result;} }
ⅳ.以上写法有什么不足呢?
还是高耦合,如果在加一个开平方根,整个程序又要重新运行;
假如现在是在做银行系统或安全系数高的,如果+,-,*,/都是各部分权限不同的人开发的,这样写它们都会互相看到;
[那我们就试试第四种方式,简单工厂的设计模式]
把Operating作为一个父类,写一些公共的东西,只是定义一个方法名,不作具体的实现操作。
class Operating { public double dNum1{get;set;} public double dNum2{get;set;} public virtual double GetResult() { double Result = 0; return Result; } }
定义一个虚方法,子类只需覆写[+的操作]
class OperAdd:Operating { //子类覆写 public override double GetResult() { double Result=0; Result = dNum1 + dNum2; return Result; } }
class OperReduce:Operating { public override double GetResult() { double Result = 0; Result = dNum1 - dNum2; return Result; } }
class OperRide:Operating { public override double GetResult() { double Result = 0; Result = dNum1 * dNum2; return Result; } }
class OperExcept:Operating { public override double GetResult() { double Result = 0; if (dNum2 == 0) { Console.WriteLine("被除数不能为0"); } else { Result = dNum1 / dNum2; } return Result; } }
定义一个工厂类OperateFactory.cs
class OperateFactory { //创建一个OperateFactory类,用于接收客户端传过来的是"+、-、*、/" public static Operating CreateOper(string sOper) { Operating oper = null; switch (sOper) { case"+": oper = new OperAdd(); //如果是+,我们就创建一个+的对象,调用GetResult(),做处理 break; case"-": oper = new OperReduce(); //如果是-,我们就创建一个-的对象 break; case"*": oper = new OperRide(); break; case"/": oper = new OperExcept(); break; } return oper; } }
再看一下客户在调用的时候的代码:
class Program { static void Main(string[] args) { Console.WriteLine("请输入第一个数:"); string sNum1 = Console.ReadLine(); Console.WriteLine("请输入运算符,+、-、*、/"); string sOper = Console.ReadLine(); Console.WriteLine("请输入第二个数:"); string sNum2 = Console.ReadLine(); string sResult=""; Operating oper; oper = OperateFactory.CreateOper(sOper); oper.dNum1 = Convert.ToDouble(sNum1); oper.dNum2 = Convert.ToDouble(sNum2); sResult = oper.GetResult().ToString(); Console.WriteLine("结果等于:"+sResult); } }
开发结果:
2.实例说明:
简单工厂设计模式:在面向对象程序设计中,对程序开发人员而言,最常见的设计模式就是简单工厂模式。简单工厂模式根据提供给它的数据,返回几个类中的一个类的实例。通常返回的类都有一个公共父类和公共方法,但是每个方法实现的功能不同,并且根据不同的数据进行初始化。
优点:工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品。简单工厂模式通过这种做法实现了对责任的分割。
低耦合,代码复用性高,扩展性强;
缺点:当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。同时,系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂。
3.简单工厂角色与结构图:
就暂时更新到这里吧,睡觉吧,毕竟身体棒棒才能继续学习。