20175306 结对编程项目-四则运算 总结博客

Posted wjs123456

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20175306 结对编程项目-四则运算 总结博客相关的知识,希望对你有一定的参考价值。

20175205 20175306 结对编程项目-四则运算 总结博客

一、第二阶段预估与实际

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划
? Estimate ? 估计这个任务需要多少时间 600 900
Development 开发
? Analysis ? 需求分析(包括学习新技术) 20 30
? Design Spec ? 生成设计文档 20 30
? Design Review ? 设计复审 20 30
? Coding Standard ? 代码规范 (为目前的开发制定合适的规范) 20 40
? Design ? 具体设计 30 40
? Coding ? 具体编码 400 600
? Code Review ? 代码复审 30 40
? Test ? 测试(自我测试,修改代码,提交修改) 20 30
Reporting 报告
? Test Repor ? 测试报告 10 20
? Size Measurement ? 计算工作量 10 10
? Postmortem & Process Improvement Plan ? 事后总结, 并提出过程改进计划 20 30
合计 600 900

二、需求分析

需求分析步骤:

  • 挖掘真实需求:此程序是给小学生准备的四则运算,包括加减乘除、括号和真分数,同时可扩展多语言选择,生成文件,去重等功能。
  • 提出解决方案:为了使程序有更强的可操作性,选择采用开-闭原则,因为如果以后想要增加开根号、幂次等运算,可以不用动整个程序,直接添加新的类就好。
  • 筛查和验证方案

三、设计思路(同时输出UML类图)

由于上课时老师讲了SOLID原则,让我们灵机一动,发现第一阶段的代码不适合扩展,于是便重新构思了一下。

SOLID

  • 单一职责原则(高内聚):让一个类只做一种类型责任,当这个类需要承当其他类型的责任的时候,就需要分解这个类。
  • 开放封闭原则:对扩展是开放的,而对修改是封闭的。
  • 代替原则:当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有is-A关系
  • 接口分离原则:不能强迫用户去依赖那些他们不使用的接口。换句话说,使用多个专门的接口比使用单一的总接口总要好。
  • 依赖倒置原则(低耦合)高层模块就不应该依赖于底层模块,二者都应该依赖于抽象模块
    技术图片

本周设计

  • 用户后期需求也许还会增加除了+、-、*、÷、()、/ 以外的符号比如需要开根号,求幂运算等等,因此我还增加了产生数学题目的抽象类
  • 增加真分数的情况,而且要添加真分数的运算,注意分母为零的情况
  • 针对于不同年龄段的学生,可能掌握的能力也不同,因此我对此也做了更改。比如,一年级能做加减运算;二年级能做乘除运算;三年级能做含括号的运算;其他年级就可做分数运算。
  • 处理生成全部题目并输出到文件,并从文件读入并判题
  • 多语言支持:简体中文, 繁體中文, English

四、实现过程中键代码解释

import java.util.Locale;
import java.util.ResourceBundle;
public abstract class Language {
    public abstract void Print(String s);
}
public class Chinese extends Language{
    public Chinese(){}
    public void Print(String s){
        Locale locale1 = new Locale("zh","CN");
        ResourceBundle res1 = ResourceBundle.getBundle("zh_CN",locale1);
        System.out.print(res1.getString(s));
    }
}
public class English extends Language{
    public English(){}
    public void Print(String s) {
        Locale locale2 = new Locale("en", "US");
        ResourceBundle res2 = ResourceBundle.getBundle("en_US", locale2);
        System.out.print(res2.getString(s));
    }
}
public class TChinese extends Language {
    public TChinese(){}
    public void Print(String s){
        Locale locale3 = new Locale("zh","TW");
        ResourceBundle res3 = ResourceBundle.getBundle("zh_TW",locale3);
        System.out.print(res3.getString(s));
    }
}

注:此处代码是为了实现程序的多语言切换(国际化),软件实现国际化,需具备以下两个特征:
1、对于程序中固定使用的文本元素,例如菜单栏、导航条等中使用的文本元素、或错误提示信息,状态信息等,需要根据来访者的地区和国家,选择不同语言的文本为之服务。
2、对于程序动态产生的数据,例如(日期,货币等),软件应能根据当前所在的国家或地区的文化习惯进行显示。

 public void Question2(int n,int stage,int grade,String Lan) {          //产生真分数
        String k = "";
        String r = "";
        for(int i=1;i<=n;i++) {
            if(Lan.equals("中文"))
                language.中文("c");
            else if(Lan.equals("英文"))
                language.英文("c");
            else
                language.繁体("c");
            System.out.println(i+":");
            int choice = op.RandomNum(3) + 1;               //随机产生运算符号的个数
            int count = 0;
            String fraction = "";
            for (int j = 1; j <= choice + 1; j++) {        //产生题目,一共应该2*choice+1个元素
                int a = num.RandomNum(10) + 1;
                int b = num.RandomNum(10) + 1;
                int gcd = GCD(a, b);
                if (gcd == a) fraction = "1";            //分子分母相同
                else {
                    if (gcd != 1) {                         //可约分
                        a = a / gcd;
                        b = b / gcd;
                    }
                    if (a < b) fraction = a + "/" + b;
                    else fraction = b + "/" + a;
                }
                s = s + fraction;                      //产生十以内的个数字
                if (count < choice) {
                    s = s + " " + op.RandomChar(4) + " ";             //在原基础上再产生字符
                    count++;
                }
            }
            s = op.RandomBranket(s,choice);
            k = Key.Key1(s);
            while(k.equals("")){
                choice = op.RandomNum(3) + 1;               //随机产生运算符号的个数
                count = 0;
                fraction = "";
                for (int j = 1; j <= choice + 1; j++) {        //产生题目,一共应该2*choice+1个元素
                    int a = num.RandomNum(10) + 1;
                    int b = num.RandomNum(10) + 1;
                    int gcd = GCD(a, b);
                    if (gcd == a) fraction = "1";            //分子分母相同
                    else {
                        if (gcd != 1) {                         //可约分
                            a = a / gcd;
                            b = b / gcd;
                        }
                        if (a < b) fraction = a + "/" + b;
                        else fraction = b + "/" + a;
                    }
                    s = s + fraction;                      //产生十以内的个数字
                    if (count < choice) {
                        s = s + " " + op.RandomChar(4) + " ";             //在原基础上再产生字符
                        count++;
                    }
                }
                s = op.RandomBranket(s,choice);
                k = Key.Key1(s);
            }

注:这里是产生真分数,真分数的难点是在约分,那么约分就要求分子分母的最大公因子,下面是求最大公因子的代码。

 public static int GCD(int a,int b){
        int m = a;
        int n = b;
        while (m != n) {
            if (m > n)
                m -= n;
            else
                n -= m;
        }
        return m;
    }

五、测试方法

技术图片

六、运行过程截图

技术图片

技术图片

技术图片

七、代码托管地址

码云链接:>https://gitee.com/wjs123456/wjs20175306/tree/master/%E7%BB%93%E5%AF%B9%E5%AD%A6%E4%B9%A0-%E5%9B%9B%E5%88%99%E8%BF%90%E7%AE%97/stage7

八、遇到的困难及法解决方法

  • 问题一:如何实现程序多语言选择(国际化)?
  • 解决过程:通过查找资料发现要想实现程序多语言选择需要输入语言包,语言包则通过key=value的形式输入,详情解释请看:>https://blog.csdn.net/youmangu/article/details/80565128
  • 问题二:如何实现去重?
  • 解决过程:我一开始的想法是,只要后缀表达式相同,那么就是相同的题目,但经过和伙伴讨论之后,又产生了新的想法,将每次进行运算的num1 op num2放入一个数组中,只要两个数组完全相同,那么就是相同的题目。(想法还在实施中)

九、对结对的小伙伴做出评价

我的小伙伴实在是太给力了!!!她的思想不断更新,一直在完善着我们的程序,让我们的程序一步步的接近实用阶段,虽然我们经过了一波好几折,但在这个过程中,我只是负责帮她梳理一下思路,给她一些建议和我的想法,然后她便能很快的将我们的想法构思出来,佩服!佩服!

十、总结(我在结对学习过程中学到的)

在本次结对过程中,由于我的小伙伴很给力,以至于我们这次的程序比较顺利的完成了,而且也完成的比较好,这样的一个程序一个人是无法写出来的,即使写出来也会漏洞百出,这就让我看到了结对学习的重要性,两个人的思想要比一个人的宽泛很多。下面来总结一下在这个过程中我学到的知识:

  • 在写程序时,不要急着下手,不要干想,而是应该先在笔和纸上画出一个大致的思路,自己和伙伴能看明白就好,然后再不断的改善,直到让自己满意为止。(或许就是我们所说的伪代码)
  • 一个程序,哪怕是已经写好的,也不是不可以改变的,虽然有时候推倒自己的程序感觉很残忍,但是当你打破常规,挖掘出新的模式时,其实对自己是一种突破
  • 在结对学习过程中,我还学会了更多关于IDEA的知识,包括测试,语言包等,发现Java的功能远不止我们所学到的这些,还有很多东西等着我们去发现和学习
  • 通过老师讲课,学到了SOLID原则,并在小伙伴的帮助下应用到了本次程序中,发现SOLID可以应用到大部分的程序中,可以让你的程序更加灵活,可操作性更强!
  • 在和小伙伴学习的过程中还学到了不懂的知识不要急着去问别人,要自己查找资料,这样你的印象才能更加深刻,别人的永远是别人的,只有学到手才是自己的!
    最后,很高兴的一次结对学习,让我学到了很多,也发现有时候两个人一起学习比一个人的效果还要好,两个人相互鼓励相互促进,共同进步!希望还能有机会和我的小伙伴一起学习!

以上是关于20175306 结对编程项目-四则运算 总结博客的主要内容,如果未能解决你的问题,请参考以下文章

20175205 结对编程项目-四则运算 总结博客

20172327 结对编程项目-四则运算 第二周 阶段总结

20172320 结对编程项目-四则运算 第二周 阶段总结

20172303 20172322 2017-2018-2 《程序设计与数据结构》结对编程项目-四则运算 项目总结

20172312『Java程序设计』课程 结对编程练习_四则运算第三周阶段总结

20172325『Java程序设计』课程 结对编程练习_四则运算第三周阶段总结