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& ...
随机推荐
- Spring IoC控制反转创建实例
Spring IoC控制反转创建实例写一个配置文件beans.xml,配置文件的约束可以访问:完整链接:https://repo.spring.io/libs-release-local/org/sp ...
- ~~函数基础(一):函数&参数~~
进击のpython 函数基础(一):参数 ==说明一点奥,如果你前置文章没有看懂,那么不建议你直接看这个== ==因为看了也是浪费时间,没有意义== 好,接下来就是Python的灵魂部分了--函数 在 ...
- WinForm控件之【DateTimePicker】
基本介绍 时间控件应用较为广泛,属性设置项也比较完善是非常好用的控件. 常设置属性.事件 CustomFormat:当Format属性设置为自定义类型时可自定义控件时间的显示格式: Enabled:指 ...
- 关于css样式加载的问题
今天我在学习jQuery的addClass操作时遇到了一个小问题,想来跟大家分享一下,避免初学者踩坑. 我的需求是制作一个表格,并让它隔行换色,在此基础上再加上鼠标悬浮变色的效果.(主要训练jQuer ...
- 【基础算法-模拟-例题-玩具谜题】-C++
原题链接P1563 玩具谜题 这道题依然是一道模拟题目,就简单讲讲坑点: 1.有些时候在转圈的时候要用到它们站成了一个环的性质! 2.小人面朝的方向影响了它们左右的方向! 3.注意考虑顺时针逆时针与小 ...
- Gitlab Runner实现NetCore自动化持续集成
目录 1.开发工具 2.GitLab服务器搭建 3.新建webapi 4.Dockerfile配置 5.配置docker-compose.yml 6.配置.gitlab-ci.yml 7.在GitLa ...
- pdo类的使用
使用方法 2.php <?php require_once "./mypdo.php"; $pdo = DAOPDO::getInstance('localhost', 'r ...
- C#中用WMI实现对驱动的查询
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Excel催化剂开源第8波-VSTO开发之异步调用方法
在VSTO开发过程中,因其和普通的Winform开发有点差别,具体细节笔者也说不清楚,大概是VSTO的插件是寄生在Excel中,不属于独立的进程之类的,其异步方法调用时,未能如Winform那样直接用 ...
- 【CodeForces - 357B】Flag Day(水题)
Flag Day Descriptions 小G请你对 n 个点进行染色,可选的颜色有三种:白.红.蓝,并使得给定的 m 个三元组中,每个点的颜色各不相同. 因为你可能不会三分图匹配,于是小G给出了更 ...