一.需求

    计算器功能需求,这个众所周知,很明确了。

二.步骤分析

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# 一个计算器功能实现引发的思考的更多相关文章

  1. 一个简单算法题引发的思考<DNA sorting>(about cin/template/new etc)

    首先是昨天在北京大学oj网上看到一个简单的算法题目,虽然简单,但是如何完成一段高效.简洁.让人容易看懂的代码对于我这个基础不好,刚刚进入计算机行业的小白来说还是有意义的.而且在写代码的过程中,会发现自 ...

  2. 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) )' #第 ...

  3. c代码中while循环的一个死机问题引发的思考

    前记   c语言已经是一门经常吃饭的本领,本来是要有种看一眼,就知道哪儿出问题了才行,没想到,遇到实际问题的时候,才知道自己的修为不到家.还没有达到那种炉火纯青的境界.看来,不是这个世界没有机会,是自 ...

  4. Spring之LoadTimeWeaver——一个需求引发的思考---转

    原文地址:http://www.myexception.cn/software-architecture-design/602651.html Spring之LoadTimeWeaver——一个需求引 ...

  5. 由一个emoji引发的思考

    由一个emoji引发的思考 从毕业以来,基本就一直在做移动端,但是一直就关于移动端的开发,各种适配问题的解决,在日常搬砖中处理了就过了,也没有把东西都沉淀下来,觉得甚是寒颜.现就一个小bug,让我们来 ...

  6. 完成一段简单的Python程序,用于实现一个简单的加减乘除计算器功能

    #!/bin/usr/env python#coding=utf-8'''完成一段简单的Python程序,用于实现一个简单的加减乘除计算器功能'''try: a=int(raw_input(" ...

  7. 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考

    2018年12月12日18:44:53 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考 案件现场 不久前,在开发改造公司一个端到端监控日志系统的时候,出现了一 ...

  8. JS事件 编程练习-自制计算器 使用JS完成一个简单的计算器功能。实现2个输入框中输入整数后,点击第三个输入框能给出2个整数的加减乘除。

    编程练习 使用JS完成一个简单的计算器功能.实现2个输入框中输入整数后,点击第三个输入框能给出2个整数的加减乘除. 提示:获取元素的值设置和获取方法为:例:赋值:document.getElement ...

  9. 由SecureCRT引发的思考和学习

    由SecureCRT引发的思考和学习 http://mp.weixin.qq.com/s?__biz=MzAxOTAzMDEwMA==&mid=2652500597&idx=1& ...

随机推荐

  1. break使用不当引发的一个“血案”

    最近在网上冲浪,读到一则新闻,摘抄下这则新闻: ======================= 以下文字摘抄自互联网==================== 1990年1月15日,AT&T电话 ...

  2. EnjoyingSoft之Mule ESB开发教程系列第五篇:控制消息的流向-数据路由

    目录 1. 使用场景 2. 基于消息头的路由 2.1 使用JSON提交订单的消息 2.2 使用XML提交订单的消息 2.3 使用Choice组件判断订单格式 3. 基于消息内容的路由 4. 其他控制流 ...

  3. 双剑合璧——掌握 cURL 和 Dig 走天涯

    如今随着大量的应用转移到网络,作为开发者,会经常做一些通讯测试,例如从网站获取信息.模拟用户向网站提交或者上传数据,查看应用通讯情况等等,现在变成了非常重要的任务. 一起来认识 cURL cURL 是 ...

  4. 洛谷 P3367 并查集 【模板题】

    题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入输出格式 输入格式: 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数Zi.Xi.Yi 当Zi=1 ...

  5. local class incompatible: stream classdesc serialVersionUID = 4125096758372084309, local class serialVersionUID = 7725746634795906143

    local class incompatible: stream classdesc serialVersionUID = 4125096758372084309, local class seria ...

  6. 个人永久性免费-Excel催化剂功能第94波-地图数据挖宝之搜索地图上的各种兴趣点数据(商铺名、地名、公共设施等)

    终于来到最激动人心的地图应用场景,将地图上的有价值的兴趣点数据一网打尽,全都收录在自己的数据源中,这个价值有多大,想想都兴奋,无数的商业场景可供挖掘,假如你还无动于衷,那要好好反思下自己做的数据分析的 ...

  7. 记一次愚蠢的经历--String不可变性

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 记录一次在写代码时愚蠢的操作,本文涉及到的知识点:S ...

  8. 2019牛客多校第一场A-Equivalent Prefixes

    Equivalent Prefixes 传送门 解题思路 先用单调栈求出两个序列中每一个数左边第一个小于自己的数的下标, 存入a[], b[].然后按照1~n的顺序循环,比较 a[i]和b[i]是否相 ...

  9. 浏览器和Node 中的Event Loop

    前言 js与生俱来的就是单线程无阻塞的脚本语言. 作为单线程语言,js代码执行时都只有一个主线程执行任务. 无阻塞的实现依赖于我们要谈的事件循环.eventloop的规范是真的苦涩难懂,仅仅要理解的话 ...

  10. Spring IoC源码探索(一)

    一.探索前:谈谈我对IoC容器的了解 IoC容器主要用于管理Bean的生命周期和对象间的关系,通过依赖注入(DI)对容器中的Bean所需要依赖的其他对象进行注入.而这一切都是在Ioc容器里边进行的,假 ...