• 结对开发 四则运算


    要求:

    1、第一阶段目标:重构四则运算-- 能把计算的功能封装起来,通过API 接口调用计算方法。

    定义一个计算核心类:把四则运算的计算功能包装在一个模块中 (这个模块可以是一个类 Class,  一个DLL等等)。

     “计算核心”模块和调用类它的其他模块之间是什么关系呢? 

    它们要通过一定的API (Application Programming Interface) 来和其他模块交流。

    这个API 接口应该怎么设计呢? 可以从下面的最简单的接口开始:

    Calc()

    这个Calc 函数接受字符串的输入(字符串里就是运算式子,例如 “ 5+3.5“,  “7/8 – 3/8 ”,  “3 + 90 * (-0.3)“  等等),这个模块的返回值是一个字符串,例如,前面几个例子的结果就是 ( ”17.5“, “ 1/2”, “-24“).

    2 第二阶段目标 - 通过测试程序和API 接口测试其简单的加减乘除功能。并能看到代码覆盖率。

    可以扩展 Calc() 的定义,让它接受一个新的参数 “precision”,  或者可以启用一个新的函数 Setting()。

    最多4 个运算符

    数值范围是 -1000 到 1000

    精度是小数点后两位

    怎么通过API 告诉我们的模块呢?  我们当然可以用函数的参数直接传递,但是参数的组合很多,怎么定义好参数的规范呢?   建议大家考虑用 XML 来传递这些参数。

    增加了新的Setting() 函数之后,要让模块支持这样的参数,同时,还要保证原来的各个测试用例继续正确地工作。

    3第三阶段目标 – 定义异常处理。

    如果输入是有错误的,例如 “1 ++ 2”, 在数值范围是 -1000 .. 1000 的时候,传进去 “10000 + 32768 * 3”,  或者是 “ 248.04 / 0”  怎么办? 怎么告诉函数的调用者 “你错了”?  把返回的字符串定义为 “-1” 来表示? 那么如果真的计算结果是 “-1” 又怎么处理呢?

     建议这个时候,要定义各种异常 (Exception), 让 Core 在碰到各种异常情况的时候,能告诉调用者 - 你错了! 当然,这个时候,同样要进行下面的增量修改:

     定义要增加什么功能 - 例如:支持 “运算式子格式错误” 异常,写好测试用例,传进去一个错误的式子,期望能捕获这个 异常。 如果没有,那测试就报错。

    在 Core 模块中实现这个功能,测试这个功能, 同时测试所有以前的功能,保证以前的功能还能继续工作 (没有 regression), 确认功能完成,继续下一个功能。

     

    //运算类封装
     
    package avshabi;
    import java.util.StringTokenizer;
    public class Calculator {
    int numerator; // 分子
    int denominator; // 分母
     
    Calculator(){
    }
     
    Calculator(int a,int b){
    if(a == 0){
    numerator = 0;
    denominator = 1;
    }
    else{
    setNumeratorAndDenominator(a,b);
    }
    }
     
    void setNumeratorAndDenominator(int a, int b){ // 设置分子和分母
    int c = f(Math.abs(a),Math.abs(b)); // 计算最大公约数
    numerator = a / c;
    denominator = b / c;
    if(numerator<0 && denominator<0){
    numerator = - numerator;
    denominator = - denominator;
    }
    }
     
    int getNumerator(){
    return numerator;
    }
     
    int getDenominator(){
    return denominator;
    }
     
    int f(int a,int b){ // 求a和b的最大公约数
    if(a < b){
    int c = a;
    a = b;
    b = c;
    }
    int r = a % b;
    while(r != 0){
    a = b;
    b = r;;
    r = a % b;
    }
    return b;
    }
     
    Calculator add(Calculator r){ // 加法运算
    int a = r.getNumerator();
    int b = r.getDenominator();
    int newNumerator = numerator * b + denominator * a;
    int newDenominator = denominator * b;
    Calculator result = new Calculator(newNumerator,newDenominator);
    return result;
    }
     
    Calculator sub(Calculator r){ // 减法运算
    int a = r.getNumerator();
    int b = r.getDenominator();
    int newNumerator = numerator * b - denominator * a;
    int newDenominator = denominator * b;
    Calculator result = new Calculator(newNumerator,newDenominator);
    return result;
    }
     
    Calculator muti(Calculator r){ // 乘法运算
    int a = r.getNumerator();
    int b = r.getDenominator();
    int newNumerator = numerator * a;
    int newDenominator = denominator * b;
    Calculator result = new Calculator(newNumerator,newDenominator);
    return result;
    }
     
    Calculator div(Calculator r){ // 除法运算
    int a = r.getNumerator();
    int b = r.getDenominator();
    int newNumerator = numerator * b;
    int newDenominator = denominator * a;
    Calculator result = new Calculator(newNumerator,newDenominator);
    return result;
    }
     
    // 封装了具体运算,主要为对输入进行转换,对输出封装
    public static void compute(String data1,String operation,String data2){
    StringTokenizer fenxi = new StringTokenizer(data1,"/");
    int data1_1 = Integer.parseInt(fenxi.nextToken());
    int data1_2 = Integer.parseInt(fenxi.nextToken());
    fenxi = new StringTokenizer(data2,"/");
    int data2_1 = Integer.parseInt(fenxi.nextToken());
    int data2_2 = Integer.parseInt(fenxi.nextToken());
     
    Calculator r1 = new Calculator(data1_1,data1_2);
    Calculator r2 = new Calculator(data2_1,data2_2);
     
    Calculator result;
    int a,b;
    if(operation.equals("+")){
    result = r1.add(r2);
    a = result.getNumerator();
    b = result.getDenominator();
    System.out.println(data1+" "+operation+" " +data2+" = " + a + "/" + b);
    }
     
    if(operation.equals("-")){
    result = r1.sub(r2);
    a = result.getNumerator();
    b = result.getDenominator();
    System.out.println(data1+" "+operation+" " +data2+" = " + a + "/" + b);
    }
     
    if(operation.equals("*")){
    result = r1.muti(r2);
    a = result.getNumerator();
    b = result.getDenominator();
    System.out.println(data1+" "+operation+" " +data2+" = " + a + "/" + b);
    }
     
    if(operation.equals("/")){
    result = r1.div(r2);
    a = result.getNumerator();
    b = result.getDenominator();
    System.out.println(data1+" "+operation+" " +data2+" = " + a + "/" + b);
    }
    }
    }
     
      
     
      
     
    // 测试类
     
    package avshabi;
     
    import java.util.Scanner;
    public class TestCal {
    public static void main(String[] args) {
    // TODO Auto-generated method stub
     
    // 用户输入两分数和运算符
    Scanner input = new Scanner(System.in);
    System.out.println("请用户输入第一个分数(格式a/b)");
    String data1 = input.next();
    System.out.println("请用户输入要进行运算的运算符(+-*/)");
    String operation = input.next();
    System.out.println("请用户输入第二个分数(格式c/d)");
    String data2 = input.next();
     
    // 根据用户输入进行具体运算
    Calculator cal = new Calculator();
    System.out.println("运算结果为:");
    cal.compute(data1, operation, data2);
    //    }   
    }
    }
     
     
    //JUint 应用测试举例
    package avshabi;
     
    import static org.junit.Assert.*;
     
    import org.junit.Test;
     
    public class CalculatorTest {
     
        @Test
        public void testAdd() {
            Calculator cal = new Calculator();
            cal.add(cal);
        }
     
        @Test
        public void testSub() {
            Calculator cal = new Calculator();
            cal.sub(cal);
        }
     
        @Test
        public void testMuti() {
            Calculator cal = new Calculator();
            cal.muti(cal);
        }
     
        @Test
        public void testDiv() {
            Calculator cal = new Calculator();
            cal.div(cal);
        }
     
        @Test
        public void testCompute() {
            Calculator cal = new Calculator();
            cal.compute("1/2", "+", "2/3");
            cal.compute("1/2", "-", "2/3");
            cal.compute("1/2", "*", "2/3");
            cal.compute("1/2", "/", "2/3");
        }
     
    }
    封装的类

    运行截图:

  • 相关阅读:
    Android SDK manager 无法更新解决方法
    platform_set_drvdata的源码分析
    从一个男人身上看出他的修养和抱负
    更换RAID1硬盘过程记录
    无线路由器连接有线路由器设置
    在ASP.NET下实现数字和字符相混合的验证码 (转载)
    不走寻常路 设计ASP.NET应用程序的七大绝招
    .NET 2005 使用MasterPages实现Web窗体模板
    用Visual C# 实现四则混合运算(转载)
    如何实施好CRM (转载)
  • 原文地址:https://www.cnblogs.com/cxy0210/p/13064601.html
Copyright © 2020-2023  润新知