zoukankan      html  css  js  c++  java
  • 四则运算之GUI

    四则运算之GUI

    一、Coding地址

     https://git.coding.net/liuc144/GUIhomework.git

    二、PSP

    PSP

    任务内容

    计划共完成需要的时间(h)

    实际完成需要的时间(h)

    Planning

    计划

    0.2

    1

    ·        Estimate

    ·   估计这个任务需要多少时间,并规划大致工作步骤

    0.2

    1

    Development

    开发

    36.5

    66

    ·        Analysis

    ·         需求分析 (包括学习新技术)

    1

    4

    ·        Design Spec

    ·         生成设计文档

    0.1

    2

    ·        Design Review

    ·         设计复审 (和同事审核设计文档)

    1

    2

    ·        Coding Standard

    ·         代码规范 (为目前的开发制定合适的规范)

    0.1

    1

    ·        Design

    ·         具体设计

    10

    12

    ·        Coding

    ·         具体编码

    20

    15

    ·        Code Review

    ·         代码复审

    3

    10

    ·        Test

    ·         测试(自我测试,修改代码,提交修改)

    1

    20

    Reporting

    报告

    3

    10

    ·         Test Report

    ·         测试报告

    0.5

    6

    ·         Size Measurement

    ·         计算工作量

    0.5

    2

    ·         Postmortem & Process Improvement Plan

    ·         事后总结, 并提出过程改进计划

    2

    2

    三、接口设计

    1、Information Hiding

    信息隐藏是指在设计和确定模块时,对于用不到的信息是禁止访问的。封装:比如求圆的面积,你只需要调用getArea(r);即可,不需要知道他是如何运行的。

    1 多层设计中的层与层之间加入接口层; 

         2 所有类与类之间都通过接口类访问;

         3 类的所有数据成员都是private,所有访问都是通过访问函数实现的.

    2、Interface Design, Loose Coupling

     接口设计和低耦合是相辅相成的,接口化设计能大大降低程序的耦合度,低耦合一定离不开接口化设计。个人理解:接口化设计就是模块化设计,让不同方法放入到不同类中,并且使得各个类相互独立,减少关联性。低耦合和接口化设计差不多,使得各个模块之间减少依赖性,从而提高容错率。

    因此,现代程序讲究高内聚低耦合,即将功能内聚在同一模块,模块与模块间尽可能独立,互相依赖低。没有绝对没有耦合的模块组,只有尽量降低互相之间的影响。使模块越独立越好。

      所以我们设计项目之初就做好了模块化设计。

      

      如文件目录显示一样,逻辑清晰,结构明显。其中CommandTest是单元测试,生成代码覆盖率的文件。

    函数之间相互调用。

      

    四、计算模块接口的设计与实现过程

     目录中各类的调用关系如图所示,简单清晰。

     

      Command.java,负责通过命令行输入的字符串数组进行识别,通过Switch判断命令是否合法(比如,命令太短或则命令太长,命令本应小写却大写,等等),通过Core获取题目后,依据文件输入输出流将题目输出到result.txt文件里。

      

      其算法核心在于生成合法的算术题(字符串),核心流程很简单,就是算术题=数字+操作符+数字+操作符...

      如何生成数字,Math.random(),其中数字大小,靠传进来的参数,lowerBoundNumber和upperBoundNumber控制。

      如何生成操作符,Operator[Math.random()],通过一个存储了操作符的字符串常量数组里随机控制下标来随机生成操作符。

    五、计算模块接口部分的性能改进

      刘畅在优化性能这个地方大概花了7、8个小时,不断的deBug和进行单元测试,始终不得眉头,我们知道哪部分出了问题——难以生成携带乘除法的算术题,后来在生成一些特殊的算术题时,刘畅对数字随机性进行一些限制。比如,当算术题中出现除法的时候,它的除数就不应该是简单的随机数,而应该是除数的因子,这样,大幅度的提高生成正确算术题的效率。同样的思想适用与乘法。

      在这里贴下关键代码

    性能分析:

    通过JProfiler,进行性能分析。

    性能分析总图:包括磁盘利用率,内存使用,CPU和线程概况。

     

    性能分析过程:

     

    按F4后,发现内存使用率比较高,只有一部分没有使用,而且即使文档都关闭了。

     

    我们继续对代码进行完善,最后内存占用率几乎100%.

     

    六、计算模块部分单元测试展示

      我们设计了很多测试,一共二十余种,其中一些测试可以合并。

        编写测试用例的思路是:正常命令

                   非正常命令

                      非正常命令包括,输入值越界,忘记输入数字(例如,只有-n),大小写错误等等

        这里列举了部分测试,更详细的请看Coding里的代码.

       

    首先我们先对单个类进行测试。

    第一组数据:对Core.java 进行了测试,测试结果如下:(表格内容分别为:覆盖率、执行的代码行数、未执行的代码行数、总行数,下同)

    第二组数据:对UI_Cmd.java 进行了测试,测试结果如下:

     

    第三组数组:对Command.java 进行测试,测试结果如下:

    第四组数组:对ToSuffix.java 进行测试,测试结果如下:

    最后对总体进行测试,结果如下: 

    代码总体覆盖率为  90.1%

    七、计算模块部分异常处理说明。

      控制台print给出错误出现场景,以下各种错误都在单独的CommandTest里用例,助教检查时运行一下就好.

      1、对n(题目的数量)进行范围限制,出现异常报错并提示用户相关信息.x

      错误用例

      错误提示

      2、对随机数的下界进行范围限制,出现异常报错并提示用户相关信息.

    错误用例:

    错误提示

      3、对随机数的上界进行限制,出现异常报错并提示用户相关信息.

    错误用例:

    错误提示:

      4、对是否有乘除法进行限制,出现异常报错并提示用户相关信息.

    错误用例:

    错误时的提示信息

     

      5、对操作符的数量进行限制,出现异常报错并提示用户相关信息.

    错误用例

    错误提示

    除此之外:还有一些是识别命令是否输入正确的异常,不过在Command模块里

      1、命令长度非法

      

      2、-n后面没有数据

      

      3、m后面数据输入错误

      

      4、程序运行时间过长

      

      结合

     八、界面模块的详细设计过程

    (项目几乎全部是由刘畅完成的,说好的我写单元测试和性能分析,代码覆盖率,但是最后单元测试代码还是刘畅完成了,性能分析、代码覆盖率找了一些人帮助才完成的,并且我对模块设计没有进行分析与设计,抱歉了)

    界面有主部分和副部分,完成之后的界面如图:

     

      主部分是:

      UI.java,JFrame框架,承载其它面板,他将面板作为实现功能的地方,这样以后想添加什么其它功能的时候方便添加,刘畅认为这一地方的设计极大的增强了扩展性,同时遵循了模块化的原则.

      副部份是:  

      UI_cmd.java,刘畅通过绝对定位布局

      部分代码如下

      

      

      绝对定位是一种很简单的布局方法,由于我们GUI不太熟练,所以我们用的绝对定位,以后有功夫会学一学其它布局方式.

      布局很简单,稍微复习下GUI然后依据绝对定位就可以设置一个简单的界面

      难的是监听器的填写.

      我们设计的是当你开始出题的时候,就显示做题界面

      然后就可以开始做题

      做题结束会告诉你花费的时间和做对的题数

      或者你可以上传题目

    然后点击做题,同样可以做题。

    这是一个监听器的编写样例.

    复制代码

    preToDo.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
    // TODO
    time = Calendar.getInstance().getTimeInMillis();
    if(url.equals(""))
    url="result.txt";
    File file = new File(url);

    if (!file.exists()) {
    JOptionPane.showMessageDialog(null, "出错了", "您需要先上传题目", JOptionPane.ERROR_MESSAGE);
    ;
    return;
    }
    labelRight.setEnabled(false);
    labelRight.setVisible(false);
    answer.setEnabled(false);
    answer.setVisible(false);
    preToDo.setVisible(false);
    preToDo.setEnabled(false);
    finish.setVisible(true);
    finish.setEnabled(true);
    nextOne.setEnabled(true);
    nextOne.setVisible(true);
    upLoadQuestion.setVisible(false);
    upLoadQuestion.setEnabled(false);
    BufferedReader reader = null;
    try {
    reader = new BufferedReader(new FileReader(file));
    String tempString = null;
    int line =1;
    // 一次读入一行,直到读入null为文件结束
    arr[0]="2016012040";
    while ((tempString = reader.readLine()) != null) {
    // 显示行号
    if(tempString.equals("2016012040"))
    continue;

    arr[line] = "第" + line + "道题:" + tempString;
    line++;
    }
    reader.close();
    } catch (IOException e1) {
    e1.printStackTrace();
    } finally {
    if (reader != null) {
    try {
    reader.close();
    } catch (IOException e1) {
    }
    }
    }
    }
    });

    复制代码

    九、界面模块与计算模块的对接

      我们设计的对接模式非常简单。

      通过获得界面参数生成一个字符串数组,然后传入Command.java的主方法

    复制代码
    preToCore.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    // TODO
                    labelTime.setEnabled(false);
                    labelTime.setVisible(false);
                    labelRight.setEnabled(false);
                    labelRight.setVisible(false);
                    answer.setEnabled(false);
                    answer.setVisible(false);
                    String[] args = new String[9];
                    try {
                        int count = 0;
                        int operator=1;
                        int n = Integer.parseInt(numberOfProblems.getText());
                        if(!numberOfOperators.getText().equals(""))
                         operator = Integer.parseInt(numberOfOperators.getText());
                        int lowerBoundNumber = Integer.parseInt(lowerBound.getText());
                        int uppperBoundNumber = Integer.parseInt(upperBound.getText());
                        Boolean isBracket = isBracketBox.isSelected();
                        Boolean isEasy = isEasyBox.isSelected();
    
                        if (n < 1 || n > 10000 || operator < 1 || operator > 10 || lowerBoundNumber > uppperBoundNumber
                                ||  lowerBoundNumber < 1 || lowerBoundNumber > 100 || uppperBoundNumber < 50
                                || uppperBoundNumber > 1000)
                            throw new Exception();
    
                        args[count++] = "-n";
                        args[count++] = n + "";
                        args[count++] = "-m";
                        args[count++] = lowerBoundNumber + "";
                        args[count++] = uppperBoundNumber + "";
                        if (!numberOfOperators.getText().equals("")) {
                            args[count++] = "-o";
                            args[count++] = operator + "";
                        }
    
                        if (isBracket)
                            args[count++] = "-b";
                        if (isEasy)
                            args[count++] = "-c";
                        for (int i = 0; i < 9; i++)
                            if (args[i] == null)
                                args[i] = "NotExit";
                        Command.main(args);
                        JOptionPane.showMessageDialog(null, "成功生成文件", "亲爱的学生您好:", JOptionPane.ERROR_MESSAGE);
                    } catch (Exception e2) {
                        // TODO: handle exception
                        e2.printStackTrace();
                        JOptionPane.showMessageDialog(null, "出错了", "请重新设置参数", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
    复制代码

    软件可完成的功能:

      1、出题功能:

      

       2、做题功能

      

      3、上传题目功能

      4、验算并记录时间和做对题数功能

    除此之外还有强大的用户友好性

    光是编写用户友好性就比实际编写核心算法的时间要长,大概花了有三十个小时.(刘畅大佬,全权包揽,抱大腿)

    十、描述结对的过程

      

    结对编程其实不是件容易的事情,你从一个人怎么高兴怎么编程,变成了需要考虑对方情绪,照顾对方,帮助对方,为对方分担压力,共享思路,修改代码的两人合作。

     十一、结对编程的好处和坏处

      结对编程的好处:

      1,在开发层次,结对编程能提供更好的设计质量和代码质量,两人合作解决问题的能力更强。

      2,对开发人员自身来说,结对工作能带来更多的信心,高质量的产出能带来更高的满足感。

      3,在企业管理层次上,结对能更有效的交流,相互学习和传递经验,分享知识,能更好地应对人员流动。总之如果运用得当,结对编程可以取得更高的投入产出比。

      它也有很多缺点:

      1、与合不来的人一起编程容易发生争执,不利于团队和谐。

      2、经验丰富的老手可能会对新手产生不满的情绪。

      3、一山不容二虎,开发者之间可能就某一问题发生分歧,产生矛盾,造成不必要的内耗。

      4、开发人员可能会在工作时交谈一些与工作无关的事,分散注意力,造成效率低下。

      我的优点:1、做事认真细心

             2、对于分配好的任务会马上去做,而且很快就会做好.

             3、态度积极

          缺点:编码基础不是很好

      刘畅的优点:1、快速设计好程序的框架。

           2、心思周全,有关程序的方方面面都有考虑到。

           3、对java语言比较熟悉.

           缺点:编码效率有些低。

     因为生了点病,现在还在医院,博客完成的也比较应付,抱歉!

  • 相关阅读:
    js积累点
    org.hibernate.NonUniqueObjectException
    SSH框架下的表单重复提交
    ajax传输中文参数乱码,本地使用tomcat不乱码,liunx+weblogic乱码
    启动weblogic报错:string value '2.4' is not a valid enumeration value for web-app-versionType in namespace http://java.sun.com/xml/ns/javaee
    weblogic启动项目,设置内容、设置的数据源链接不生效
    myeclipse编译弹框:The builder launch configuration could not be found
    tomcat启动项目报错:The specified JRE installation does not exist
    Mac上的jdk
    前端
  • 原文地址:https://www.cnblogs.com/lirc331/p/8776240.html
Copyright © 2011-2022 走看看