C# 一个计算器功能实现引发的思考
一.需求
计算器功能需求,这个众所周知,很明确了。
二.步骤分析
1)初级实现计算器
static int Calculator(int a,int b,string str)
{
switch(str)
{
case "+":
return a + b;
case "-":
return a - b;
case "*":
return a * b;
case "/":
return a / b;
}
return ;
}
优势:代码简单。
劣势:如果新增需求,需要不断在switch中增加分支,并且需要在对应分支写上相应的逻辑代码。代码耦合度太高。违背对修改关闭原则。
2)中级实现计算器
I.先看case分支中对应的操作,都是运算。即,我们可以把其实现抽象出来。
II.因为我们知道所有的运算都是对两个数进行运算,所以,可以抽象出一个抽象类,即运算抽象基类BaseCalculate。
public abstract class BaseCalculate
{
public abstract int Calculate(int a, int b);
} public class Add : BaseCalculate
{
public override int Calculate(int a, int b)
{
return a + b;
}
} public class Sub:BaseCalculate
{
public override int Calculate(int a, int b)
{
return a - b;
}
}
优势:这个操作,我们将case中分支的代码抽象出来了。在对应的运算子类中更改其操作就可以。将具体实现抽离出来。
劣势:代码量增加,违背了开放-封闭原则。(即开放增加,封闭修改原则)
上述,就是设计模式中,传说的简单工厂模式
3)高级实现计算器
class Program
{
static void Main(string[] args)
{
BaseFactory factory = new AddFactory();
Console.WriteLine(factory.GetCalculate().Calculate(, )); BaseFactory factory2 = new SubFactory();
Console.WriteLine(factory2.GetCalculate().Calculate(, ));
Console.Read();
}
} public abstract class BaseFactory
{
public abstract BaseCalculate GetCalculate();
} public class AddFactory:BaseFactory
{
public override BaseCalculate GetCalculate()
{
return new Add();
}
} public class SubFactory:BaseFactory
{
public override BaseCalculate GetCalculate()
{
return new Sub();
}
}
这就是传说中工厂方法模式,与上述简单工厂模式对比克服了开放-封闭原则。
优势:减去核心逻辑中的switch分支。
劣势:代码量又增加了。
4)扩展&补充
如果说上述的设计只为int型运算,如果现在需求增加,还需要增加 专门精度为float计算的计算器。上述计算,只针对int型,现在要专门是float型,该如何?
所以,我们只需要增加基类BaseFloatCalculate,然后进行各种实现。并在BaseFactory中增加 BaseFactory GetFloatCalculate() 即可。代码就不贴了,这其实就是扩展。
这就是抽象工厂模式。
即使上述种种,还是离不开switch分支问题,有可以解决分支问题的办法吗。有的,但是不算主流,可以利用反射。
BaseCalculate cal = (BaseCalculate)Assembly.Load("ConsoleApp7").CreateInstance("ConsoleApp7.Sub");
Console.WriteLine( cal.Calculate(, ));
三.总结
所谓优秀的功能的实现代码,即需要符合高聚酯,低耦合。
符合高聚酯,低耦合,那就离不开架构设定。
架构设计,其实无非就是即不断的抽象,对类抽象,对方法抽象。当然,也不能过度抽象,会造成冗余。
因此总结一下,架构设定,就是合理适度的抽象。
笔者认为
没有绝对适合某功能的架构框架,只有绝对合理适度的抽象。
C# 一个计算器功能实现引发的思考的更多相关文章
- 一个简单算法题引发的思考<DNA sorting>(about cin/template/new etc)
首先是昨天在北京大学oj网上看到一个简单的算法题目,虽然简单,但是如何完成一段高效.简洁.让人容易看懂的代码对于我这个基础不好,刚刚进入计算机行业的小白来说还是有意义的.而且在写代码的过程中,会发现自 ...
- python 实现一个计算器功能
#s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )' #第 ...
- c代码中while循环的一个死机问题引发的思考
前记 c语言已经是一门经常吃饭的本领,本来是要有种看一眼,就知道哪儿出问题了才行,没想到,遇到实际问题的时候,才知道自己的修为不到家.还没有达到那种炉火纯青的境界.看来,不是这个世界没有机会,是自 ...
- Spring之LoadTimeWeaver——一个需求引发的思考---转
原文地址:http://www.myexception.cn/software-architecture-design/602651.html Spring之LoadTimeWeaver——一个需求引 ...
- 由一个emoji引发的思考
由一个emoji引发的思考 从毕业以来,基本就一直在做移动端,但是一直就关于移动端的开发,各种适配问题的解决,在日常搬砖中处理了就过了,也没有把东西都沉淀下来,觉得甚是寒颜.现就一个小bug,让我们来 ...
- 完成一段简单的Python程序,用于实现一个简单的加减乘除计算器功能
#!/bin/usr/env python#coding=utf-8'''完成一段简单的Python程序,用于实现一个简单的加减乘除计算器功能'''try: a=int(raw_input(" ...
- 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考
2018年12月12日18:44:53 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考 案件现场 不久前,在开发改造公司一个端到端监控日志系统的时候,出现了一 ...
- JS事件 编程练习-自制计算器 使用JS完成一个简单的计算器功能。实现2个输入框中输入整数后,点击第三个输入框能给出2个整数的加减乘除。
编程练习 使用JS完成一个简单的计算器功能.实现2个输入框中输入整数后,点击第三个输入框能给出2个整数的加减乘除. 提示:获取元素的值设置和获取方法为:例:赋值:document.getElement ...
- 由SecureCRT引发的思考和学习
由SecureCRT引发的思考和学习 http://mp.weixin.qq.com/s?__biz=MzAxOTAzMDEwMA==&mid=2652500597&idx=1& ...
随机推荐
- Bzoj 1040 [ZJOI2008]骑士 题解
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5368 Solved: 2044[Submit][Status ...
- Kafka部署
Kafka依赖Zookeeper,虽然Kafka自带zookeeper,但是建议单独部署,所以先部署Zookeeper. 测试环境 citus1,citus2,citus3三台机器.对主机名和ip在/ ...
- pip install xxxx报错(一大堆红色exception)【解决】
安装个distribute或nose或lpthw.web或virtualenv 都可能出现下面问题 root@kali:~# pip install distribute Collecting d ...
- 查看内存的方法。vs-调试-窗口-内存
1.vs-调试-窗口-内存 2.把指针复制到内存窗口中,就可以查看窗口的内存了.
- CF510C Fox And Names——拓扑排序练习
省委代码: #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> # ...
- 网络IP的操作
10.10.10.10/8求解问题:子网掩码 10.255.255.255该IP地址所在网络的网络ID 10.0.0.0该IP地址所在网络的广播地址 10.255.255.255该IP地址所在网络的I ...
- Python学习3——Python的简单推导
列表推导是一种从其他列表创建列表的方式,类似于数学中的集合推导,列表推导的工作原理非常简单,类似于for循环.(以下代码均在IDLE实现) 最简单的列表推导: >>>[x*x for ...
- android异常 More than one file was found with OS independent path 'META-INF/XXX'
android 异常总结:一个文件在jar包中出现多次. Error:Execution failed for task ':app:transformResourcesWithMergeJavaRe ...
- 使用nginx+tomcat实现动静分离
动态资源与静态资源的区别 微微的概括一下 静态资源: 当用户多次访问这个资源,资源的源代码永远不会改变的资源. 动态资源:当用户多次访问这个资源,资源的源代码可能会发送改变. 什么是动静分离 动静分离 ...
- 性能测试-loadrunner参数化
工具:loadrunner11 ie8 场景:不同用户的登录 1.参数化功能: 让脚本使用批量的变化的数据测试,实现模拟不同数据/用户的行为 函数格式:返回值类型 函数名称(参数类型 参数,参数类型 ...