zoukankan      html  css  js  c++  java
  • 20175205 结对编程项目-四则运算 总结博客

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

    需求分析(描述自己对需求的理解,以及后续扩展的可能性)

    • 需求分析
      • 用户需求(往往不是真实需求)
      • 产品需求(对用户需求提炼分析)
    • 需求分析的步骤
      • 挖掘真实需求(需要透过现象看本质,挖掘真实需求)
        • 目标用户
        • 使用场景
        • 想要解决的问题
      • 提出解决方案(不只局限于用户的需求)
      • 筛选和验证方案

    针对于本问题:

    用户需求

    • 自动生成小学四则运算题目(加、减、乘、除);支持整数;支持多运算符(比如生成包含100个运算符的题目);支持真分数;统计正确率
    • 扩展需求:文件,处理生成题目并输出到文件,完成题目后从文件读入并判题;多语言支持:简体中文, 繁體中文, English;生成题目去重

    分析需求

    • 挖掘真实需求:
      • 目标用户:小学生
      • 使用场景:小学生进行数学有关四则运算题目的测试
      • 想要解决的问题:设计一个可以让学生测试的程序
    • 提出问题和解决方案:让用户可以进行数学测试,可以是数学四则运算测试,还可以是"开根号,幂运算"等等,还可以支持更多语言。

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

    上课讲了SOLID原则,反看第一周完成的代码,那都是个什么玩意,充分的满足了“低内聚,高耦合”,添加新要求的时候,一动都得动,无从下手,因此我决定重新修改,试着向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、对于程序动态产生的数据,例如(日期,货币等),软件应能根据当前所在的国家或地区的文化习惯进行显示。

    if(s1.equals("1")&&(s2.equals("1")==false)){
                Numerator1 = 1;
                Denominator1 = 1;
                str2 = s2.split("/");
                Numerator2 = Integer.parseInt(str2[0]);
                Denominator2 = Integer.parseInt(str2[1]);
            }
            else if(s2.equals("1")&&(s1.equals("1")==false)){
                Numerator2 = 1;
                Denominator2 = 1;
                str1 = s1.split("/");
                Numerator1 = Integer.parseInt(str1[0]);
                Denominator1 = Integer.parseInt(str1[1]);
            }
            else if(s1.equals("1")&&s2.equals("1")){
                Numerator1 = 1;
                Denominator1 = 1;
                Numerator2 = 1;
                Denominator2 = 1;
            }
            else{
                if((s1.contains("/")==true)&&(s2.contains("/")==false)){
                    str1 = s1.split("/");
                    Numerator2 = Integer.parseInt(s2);
                    Denominator2 = 1;
                    Numerator1 = Integer.parseInt(str1[0]);
                    Denominator1 = Integer.parseInt(str1[1]);
                }
                else if((s2.contains("/")==true)&&(s2.contains("/")==false)){
                    Numerator1 = Integer.parseInt(s1);
                    Denominator1 = 1;
                    str2 = s2.split("/");
                    Numerator2 = Integer.parseInt(str2[0]);
                    Denominator2 = Integer.parseInt(str2[1]);
                }
                else if((s2.contains("/")==false)&&(s2.contains("/")==false)){
                    Numerator1 = Integer.parseInt(s1);
                    Denominator1 = 1;
                    Numerator2 = Integer.parseInt(s2);
                    Denominator2 = 1;
                }
                else{
                    str1 = s1.split("/");
                    str2 = s2.split("/");
                    Numerator1 = Integer.parseInt(str1[0]);
                    Denominator1 = Integer.parseInt(str1[1]);
                    Numerator2 = Integer.parseInt(str2[0]);
                    Denominator2 = Integer.parseInt(str2[1]);
                }
            }
    

    这个部分是我一开始没有想到的情况,通过测试等手段发现了分母为零的情况,不是分数的情况。

    测试方法

    运行过程截图



    代码托管

    遇到的困难及解决方法

    Q: 将带有÷号的题目输入文件,却出现了乱码。。。心态爆炸,本来好好的程序,加了个文件就输不出来了???
    A:原来是系统的编码和程序的编码采用了不同的编码格式。在用Java程序进行读写含中文的txt文件时,经常会出现读出或写入的内容会出现乱码。通常,假如自己不修改的话,windows自身采用的编码格式是gbk(而gbk和gb2312基本上是一样的编码方式),而IDE中Encode不修改的话,默认是utf-8的编码,这就是为什么会出现乱码的原因。当在OS下手工创建并写入的txt文件(gbk),用程序直接去读(utf-8),就会乱码。为了避免可能的中文乱码问题,最好在文件写入和读出的时候显式指定编码格式。因此,我在输入读写文件上做了改动,表明了编码格式!!

    try{
                        OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(file),"gbk");
                        BufferedWriter writer = new BufferedWriter(write);
                        writer.write(t);
                        writer.write(" = ");
                        writer.close();
                    }
                    catch (IOException e){}
                    try{
                        InputStreamReader read = new InputStreamReader(new FileInputStream(file),"gbk");
                        BufferedReader reader = new BufferedReader(read);
                        System.out.print(reader.readLine());
                        read.close();
                    }
                    catch (IOException e){}
    

    Q:多语言支持是什么鬼。。。就一直if-else??
    A:Java中有ResourceBundle这样的类,可以做到

    • 轻松地本地化或翻译成不同的语言
    • 一次处理多个语言环境
    • 以后可以轻松进行修改,以便支持更多的语言环境
      这个类的作用就是读取资源属性文件(properties),然后根据.properties文件的名称信息(本地化信息),匹配当前系统的国别语言信息(也可以程序指定),然后获取相应的properties文件的内容。具体实施就是:
    • 在src目录下建后缀为properties的文件,我的理解是,可以一个语言体系建一个对应的读取资源属性文件
    • 文件里面放的内容是我想输出的字符串所对应的ASCII(可用ASCII转换器)
    • 我建了一个Language的类,里面包含3个方法,分别是中英繁体的实现;需要英文时,就调用实现英文的方法即可

    Q:如何实现去重
    A:我一开始的想法是,只要后缀表达式相同,那么就是相同的题目,但经过和伙伴讨论之后,又产生了新的想法,将每次进行运算的num1 op num2放入一个数组中,只要两个数组完全相同,那么就是相同的题目。(想法还在实施中)

    对结对的小伙伴做出评价(重点指出需要改进的地方)

    哇,小伙伴简直太重要了,我听了老师的各种原则之后,看我的程序简直是一团乱麻,剪不断理还乱,藕断丝连,你中有我,我中有你。。。因此我决定,按照SOLID原则及需求分析步骤,和我的小伙伴激烈讨论,给我提供了非常好的思路,重新整理了我的程序。我发现,在完成扩展内容的时候,就可以做到对外扩展,对内封闭,非常开心!和小伙伴的合作很顺利,我们分工明确,积极讨论,互相改错,相互进步,在此次结对学习过程中受益匪浅,不仅对知识点有了巩固和拓展,还对编程的思路方式等有了新的模式。

    参考

    Java读写txt文件时防止中文乱码问题出现的方法介绍
    JAVA中ResourceBundle使用详解

    PSP

    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

    总结学到的内容

    这次做结对项目本着可以学到东西的目的,我对自己的代码的大致模型改了很多次,第一周自己尝试的时候虽然做出了符合要求的程序,但是内在关系还是非常杂乱的,完全不满足SOLID原则;在听了相关讲解之后,对设计模式,如何做需求分析,怎样写出高内聚低耦合的程序有了一定的了解,因此我努力的对自己的程序不断修改,努力完成一份符合设计原则的代码;在个过程中遇到了非常多的问题,解决完这个问题,又会产生下个问题等待优化,我不得不上网百度,和同学讨论,这样两个思想的碰撞产生的是无穷的力量,不仅增加了我的知识储备,还大大提高了自己的抗压能力,写完代码非常有成就感。

  • 相关阅读:
    PAT 1005. 继续(3n+1)猜想 (25)
    PAT 1004. 成绩排名 (20)
    android小游戏 飞机躲子弹
    PAT 1004. 成绩排名 (20) JAVA
    PAT 1003. 我要通过!(20) JAVA
    PAT 1003. 我要通过!(20)
    PAT 1002. 写出这个数 (20)
    NEERC, Northern Subregional Contest 2012 B 乱搞or搜索
    SGU 167 未解 dp
    Bucharest, Romania 2013 A Russian Dolls 贪心
  • 原文地址:https://www.cnblogs.com/orii/p/10636575.html
Copyright © 2011-2022 走看看