工作了两年,之前只是知道设计模式这个东西,并没有很系统的学过,在写代码的过程中意识到这个东西他还真的很有用,正好也再看大话设计模式这本书,觉得应该好好研究下了,在博客记录下来,感觉大部分都会跟书上一样,我希望可以尽量缩减并加上自己的理解,嗯。。先这样叭0.0,先定个小目标,写够5篇 ̄□ ̄||,Come On !!!
我们从一个基本的计算器逻辑开始,要求输入两个数字和计算符号,得到相应的结果,如果让你写应该怎么写呢?
最直观的应该就是这样了吧:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("请输入数字A:");
string A = Console.ReadLine();
Console.WriteLine("请输入运算符号(+、-、*、/):");
string B = Console.ReadLine();
Console.WriteLine("请输入数字B:");
string C = Console.ReadLine();
string D = "";
if (B == "+")
D = Convert.ToString(Convert.ToDouble(A) + Convert.ToDouble(C));
if (B == "-")
D = Convert.ToString(Convert.ToDouble(A) - Convert.ToDouble(C));
if (B == "*")
D = Convert.ToString(Convert.ToDouble(A) * Convert.ToDouble(C));
if (B == "/")
D = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(C));
Console.WriteLine("结果是:"+D);
}
}
那么,上面这串代码有什么问题呢?
先说最基本的问题:
1.命名不规范
2.分支判断累赘
3.没有做报错判断,当除数为0或者其他东西时会报错
解决办法:
1.规范命名:例如A->NumberA,B->Operate,C->NumberB
2.if改为Switch判断
3.加入try-catch异常捕捉
这样基本的代码实现是没有问题了,但是我们说的是设计模式啊,这样显然不符合我们的预期的!!
首先我们了解一下什么是面向对象编程:
简单来说就是在看到一个问题的时候应该想的是这个问题会涉及到哪些对象,对象里有什么属性,对象和对象之间的关系是怎么样的,我们在通过封装、继承、多态把程序的耦合度降低优化。(这也太抽象了= =)
那么现在我们终于跨出了第一步,那么,如果让你封装下上面的那个程序你们怎么封装呢?
我们可能会将运算的部分单独封装到一个类中,就是让业务逻辑和界面逻辑分开,让他们的耦合度降低
public class Operation
{
public static double GetResult(double numberA,double numberB,string operate)
{
double result = 0d;
switch (operate)
{
case "+":
result = numberA + numberB;
break;
case "-":
result = numberA - numberB;
break;
case "*":
result = numberA * numberB;
break;
case "/":
result = numberA / numberB;
break;
default:
break;
}
return result;
}
}
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("请输入数字A:");
string numberA = Console.ReadLine();
Console.WriteLine("请输入运算符号(+、-、*、/):");
string operate = Console.ReadLine();
Console.WriteLine("请输入数字B:");
string numberB = Console.ReadLine();
string result = "";
result = Convert.ToString(Operation.GetResult(Convert.ToDouble(numberA), Convert.ToDouble(numberB), operate));
Console.WriteLine("结果是:" + result);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("输入有错"+e);
}
}
}
终于完成了·~~~但是突然有个要求,让再次基础上加一个开根号的运算会怎么办呢?
可能会想在switch上在加一个分支不就好了,可是如果这样的话就会涉及到加减乘除的逻辑,我们并不希望这样,那我们是不是应该将他们分开呢?
public class Operation
{
private double _numberA = 0;
private double _numberB = 0;
public double NumberA {
get { return _numberA; }
set { _numberA = value; }
}
public double NumberB
{
get { return _numberB; }
set { _numberB = value; }
}
public virtual double GetResult()
{
double result = 0;
return result;
}
}
class OperationAdd: Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA + NumberB;
return result;
}
}
class OperationSub : Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA - NumberB;
return result;
}
}
class OperationMul : Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA * NumberB;
return result;
}
}
class OperationDiv : Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA / NumberB;
return result;
}
}
这样他们之间就不会互相影响了,但是这样我们要怎么调用想用的算法呢,,这里就用到了简单工厂模式了:
public class OperationFactior
{
public static Operation createOperate(string operate)
{
Operation oper = null;
switch (operate)
{
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
default:
break;
}
return oper;
}
}
class Program
{
static void Main(string[] args)
{
try
{
Operation oper;
oper = OperationFactior.createOperate("+");
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();
Console.WriteLine("结果是:"+ result);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("输入有错"+e);
}
}
}
当当当·~恭喜你~~一个简单的工厂模式就完成了~~是不是很简单啊~~
结构图如下: