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

    四则运算之GUI

    Coding克隆地址:https://git.coding.net/lvgx/pair_programming.git
     

    目录:

    一、前言

    二、计划时间——PSP

    三、接口设计

    四、接口实现

    五、性能分析

    六、单元测试

    七、异常处理

    八、模块设计

    九、模块对接

    十、她

    十一、结对编程思考

    十二、实际时间——PSP


    一、前言

    首先我很感谢我的队友——吕国馨(www.cnblogs.com/lvgx/p/8733486.html),谢谢她清明假期仍在认真的敲代码,放弃自己休息的时间。第二我要感谢一位大佬,当我对GUI没丝毫头绪时,大佬的一篇博客给了我启发。

    下面带上大佬博客:www.cnblogs.com/mafx/p/8536796.html

    二、计划PSP

    PSP

    任务内容

    计划时间(min)

    Planning

    计划

    30

         Estimate

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

    30

    Development

    开发

    35*60+25

        Analysis

        需求分析

    60

        Design Spec

        生成文档

    0

        Design Review

        设计复审

    2*60

        Coding Standard

        代码规范

    10

        Design

        具体设计

    12*60

        Coding

        具体编码

    2*8*60

        Code Review

        代码复审

    4*60

        Test

        测试

    15

    Reporting

    报告

    5.5*60

        Test Report

        测试报告

    60

        Size Measurement

        计算工作量

    30

       Postmortem& ProcessImprovement Plan

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

    4*60

    尤其在编程GUI时候,花费了大量的时间。

    三、接口设计

    1、Information Hiding

    信息隐藏是指在设计和确定模块时,对于用不到的信息是禁止访问的。封装:比如求圆的面积,你只需要调用getArea(r);即可,不需要知道他是如何运行的。宏定义:可以用宏定义对信息进行隐藏,比如#define PI 3.1415926。当你需要使用π时,直接使用PI就行了,你不需要知道PI的具体值。

    我们的设计:进行模块化设计,通过对函数的封装。只可以调用方法,不可以改变内部变量。界面化设计:你只需要知道如何使用它,不需要知道界面内部是如何运行的。变量设置为私有的。

    2、Interface Design, Loose Coupling

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

    我们的设计:我们已经尽我最大的努力,来进行模块化设计了,比如界面生成和算式生成是相互独立的,优先级判断、计算结果和算式生成又是相互独立的。但是我们的程序还有很多不足,比如界面设计,我们的五个界面都在同一个函数中实现的。原本我们尽力让他们在不同函数中,但是在继承时过程中,总是出现错误,最后我们还是放弃了。Java的继承我们还要再学一学。

    四、接口实现

     本次界面程序一共用到了9个类,14个函数,此9个类的调用关系如下图:

    我们此界面程序的关键之处在于监听器的运用,大概用到了3个监听器,分别是复选框监听器、按钮监听器、文件监听器,本打算使用时间监听器,来计算当前时间和用时,但是发现可以直接调用java中自带的类,方便起见,就没有使用。代码的独特之处在于:界面套界面。即是亮点又是污点,亮点在于方法简单,实现方便,容易掌握(灵感来源于:www.cnblogs.com/mafx/p/8536796.html)。同时这也是一个不好之处,导致程序无法分解,耦合度太高,后期维护困难。

    五、性能分析

    说句实话,自我感觉能完成这个项目就很不错了,还要什么性能优化呀。。。但是我们已经尽力优化性能了,比如挺高代码利用率了。比如Puanduan类,和Yunsuan类,我们把它两生成两个类,其他类直接调用,减少代码长度。尽量减少内存开支,比如不定义数组,改用容器,因为数组的每个存储单元利用率不高。一般数组我们都往大的开,因为怕其不够用,但是这种方法会导致,大量内存单元没有被利用。题目要求最大生成10000到题目,如果你开10000大小的数组,当我们只生成10道题时,会有99990个内存没被利用。我们还尽量减少循环套循环,从而减少时间的消耗。

    如何性能分析?百度上说是,进行溢出测试,将代码进行死循环,使得当CPU达到100%时,查看时间,时间越短,性能越好。

    我们的分析方法是:通过JProfiler,进行性能分析。

    总体分析图:包括CPU,内存,线程等等。

    性能分析过程:

    我们用三组数据分别对三个主要函数进行时间上的测试:

    函数一:Algorithm函数,他用时最短,只用了11640微妙,且30%的原因在于文本的输入与输出,这是无法避免的,所以未进行优化。

    函数二:Algorithm2函数,用时37789微妙,此函数30%的用时是在调用JiSuan函数上,JiSuan的用时主要是在出栈上,也是无法避免的。

    函数三:Algorithm1函数用时最长,用时60390微妙,此函数用时主要是循环,此函数中有一个三重循环和大量二重循环,导致了时间过长。从图像也可以看出,橙色占的比例接近90%(橙色代表,阻碍与消耗,不是正常运行程序时间)。

     

    性能优化:对于循环过多的Algorithm1函数,进行了优化,减少了几个循环,之后,我们又减少了大量循环,因为老师的需求降低(中间过程可以保证不再范围之内,这使得我们的程序,更加简洁)

    可见,时间明显降低!

    我们还对界面程序的性能进行分析,和优化,改进,文件也通过ps.close();进行关闭,按F4再一次查看,内存占用率明显减少,文件也都关闭了,但是仍有内存没释放,我们会继续改进的,性能分析结果如下。

    六、单元测试

    测试单元代码:

     1 public class Test {
     2     
     3     private static int n=10;
     4     private static int m1=1;
     5     private static int m2=50;
     6     private static int o=4;
     7     private static int c=0;    
     8     private static String s="11+(43-(35-(14+26)))";
     9     
    10     public static void main(String[] args) {
    11         // TODO Auto-generated method stub
    12         Command.main(null);// 主界面
    13         System.out.println(Algorithm.Algorithm(n, m1, m2, c, o)); //生成题目函数一
    14         System.out.println(Algorithm.Algorithm(n, m1, m2, c, o)); //生成题目函数二
    15         System.out.println(Algorithm.Algorithm(n, m1, m2, c, o)); //生成题目函数三
    16         GUI.main(null);  // 中文界面
    17         GUI1.main(null); // 英文界面
    18         //JiSuan.JiSuan(s);
    19     }
    20 
    21 }

    我们对9个类进行了测试:采用结合或者独立的测试方法,来分别观察其代码覆盖率。(表中分别为:函数名、覆盖率、执行行数、错过行数、总行数)

    第一组数据:

    Command.java:这是一个语言选择窗口。

    Algorithm.java:是一个可以生成加减乘除并且带有括号式子的类。

    JiSuan.java:是一个可以计算式子,并且返回结果的类。

    Panduan.java:是一个判断运算符优先级的类

    测试结果如下:

    第二组数据:

    GUI.java和GUI1.java:分别是生成汉语出题窗口和英语出题窗口、汉语上传文件和英语上传文件的窗口。测试结果如下:

    第三组数据:

    YunSuan.java:一个进行简单加减乘除运算的类。测试结果如下:

    第四组数据:

    Algorithm1.java:是一个能生成乘除不带括号和不带乘除不带括号式子的类。测试结果如下:

    Algorithm2.java:是一个生成不带乘除带括号式子的类。测试结果如下:

     

    总体来说,代码覆盖率为:91.47%

    七、异常处理

     异常处理一:就是对输入出题数、运算符个数、范围等进行判断,判断其是否合法或者超出其范围。(只展示了,出题数的代码,其他雷同)

     1 try {
     2     n1 = Integer.parseInt(n.getText());
     3     if (n1 <= 0 || n1 > 10000) {
     4         n.setText("n的范围不在[1,10000]内,请重新输入");
     5         return;
     6     }
     7     flag0 = 1;
     8 } catch (Exception a) {
     9     n.setText("n的格式不合法,请重新输入!");
    10 }

    对应场景:

    异常处理二、文件异常处理

    1 try {
    2     ps = new PrintStream("result.txt");// 生成文件
    3     System.setOut(ps);
    4 } catch (Exception e) {
    5     System.out.println("文件生成错误");// 提示
    6 }

    对应场景:

    点击出题时,如果文件生成错误,将不再生成。

    异常处理三:文件过滤

    1 FileNameExtensionFilter filter = new FileNameExtensionFilter("war", "xml", "txt", "doc", "docx");

    对应场景:

    只能找到此格式的文件,其他格式文件,都被过滤了。

    异常处理四:编码异常

    1 InputStreamReader read = new InputStreamReader(new FileInputStream(f), "UTF-8");

    对应场景:

    只能处理UTF-8文件,要不会出现乱码。

    异常处理五:用户不存在异常

    如果你没有注册,即文件中没你的用户信息,会报用户不存在异常。

     1 int flag = yanZheng(user.getText(), password.getText());
     2 if (flag == 1) {
     3     GUI.main(null);
     4 } else if (flag == 0) {
     5     user.setText("密码错误!");
     6     return;
     7 } else {
     8     user.setText("账号不存在!");
     9     return;
    10 }

    对应场景:

      异常处理六:用户和密码不匹配

    即当用户存在时,但是密码输入和注册时的不同时,会报密码错误。代码如上:

    对用场景:

      异常处理七:用户已存在

    即当注册过程中,如果该用户已存在,会报用户已存在错误。

    1 int temp = yanZheng(user.getText(), password.getText());
    2 if(temp==0||temp==1)
    3 {
    4     user.setText("账号已存在,请重新注册!");
    5     return ;
    6 }

    对应场景:

    异常处理八:注册信息不合法

    注册时,对账号和密码有一定限制,当超出限制时,会报错。

     1 try {
     2     int user1 = Integer.parseInt(user.getText());
     3     if (user1 <= 0 || user1 >= 1000000) {
     4         user.setText("用户名多余6位,或者不合法!");
     5         return;
     6     }
     7 } catch (Exception a) {
     8     user.setText("账号有多余字符(只能是数字),请重新注册!");
     9     return;
    10 }
    11 try {
    12     int password1 = Integer.parseInt(password.getText());
    13 } catch (Exception a) {
    14     user.setText("密码有多余字符(只能是数字),请重新注册!");
    15     return;
    16 }

      为了方便起见,限制有点严格,必须是数字字符串,而且不能超过6位,其实不太合理,但是程序实现很简单。

    对应场景:

    八、模块设计

    1、首先先设计一个语言选择功能,可以进行语言选择,通过按钮和调用函数来实现。

     1 private JButton jcChina = new JButton("中文");//两个按钮,分别生成两种不同语言的界面
     2 private JButton jcEnglish = new JButton("English");//可以用一个数组,存入多种语言,实现多语言转化
     3 jcChina.addActionListener(new ActionListener() {//按钮监听器,为了实现中文界面
     4     @Override
     5     public void actionPerformed(ActionEvent e) {
     6         GUI.main(null);
     7     }
     8 });
     9 jcEnglish.addActionListener(new ActionListener() {//按钮监听器,为了实现英文界面
    10     @Override
    11     public void actionPerformed(ActionEvent e) {
    12         GUI1.main(null);
    13     }
    14 });

    2、然后进行出题界面设计,此界面就是简单的GUI界面设计。

     1 JPanel p1 = new JPanel();
     2 p1.setLayout(new GridLayout(4, 2, 5, 5));
     3 p1.add(new JLabel("出题数[1,10000]:"));
     4 p1.add(n);
     5 p1.add(new JLabel("数值左边界[1,100]:"));
     6 p1.add(m1);
     7 p1.add(new JLabel("数值右边界[50,1000]:"));
     8 p1.add(m2);
     9 p1.add(new JLabel("运算符数[1,10]:"));
    10 p1.add(o);

    3、然后进行上传文件的界面设计,此界面可以直接调用,java中已经有了。

    1 JFileChooser chooser = new JFileChooser();
    2 chooser.setMultiSelectionEnabled(true);
    3 // 过滤文件类型 
    4 FileNameExtensionFilter filter = new FileNameExtensionFilter("war", "xml", "txt", "doc", "docx");
    5 chooser.setFileFilter(filter);

    4、然后设计答题界面设计,此界面和出题界面类似,但是调用方法不同,在下面我会讲到。

     1 JPanel panel2 = new JPanel();
     2 JTextField text = new JTextField(10);
     3 panel2.setLayout(new GridLayout(3, 2, 5, 5));
     4 label.setText(addProblem());
     5 panel2.add(label);
     6 panel2.add(new JLabel("/*为了美观*/"));
     7 panel2.add(new JLabel("请输入答案:"));
     8 panel2.add(text);
     9 panel2.add(jbnext);
    10 panel2.add(jbsubmit);

    5、统计页面设计,内容设计,改用调用list实现。

    1 JPanel panel = new JPanel();
    2 panel.add(new JLabel(
    3         "做题总数: " + size + " " + "  正确数:" + rightAnswer + "  用时(S):" + (t2 - t1) / 1000));
    4 setLayout(new GridLayout(100, 1, 5, 5));
    5 for (int i = 0; i < size; i++) {
    6     panel.add(new JLabel(list.get(i)));
    7 }
    8 resultFrame.add(panel);

    九、模块对接

    1、语言选择功能

     

    相当于主函数,它通过按钮调用GUI和GUI1类

    2、出题功能

    它也是通过按钮调用做题界面和上传界面。

     

    3、做题功能

    通过下一题按钮进行判断和再次出题,通过按钮调用统计界面。

    4、统计和计时

    最终页面,不进行调用。代码如下:

    5、上传文件及解析

    代码如下:

    调用提交和下一题按钮,代码和上面一样,但是会有一个上传成功的提示,代码如下:

     6、用户注册和登录功能

    没有注册的用户必须注册后才能进入程序进行答题和出题界面。

    通过按钮对模块之间进行连接。

    十、她

    我们原本打算做前端,即Web的四则运算程序,而且她已经完成了,前端开发,如图:

    但是由于我不会套页,即不能和后端连起来。所以最后放弃了Web项目,改做GUI。让她白做了一场,惭愧(就当给她个机会,让她练习练习前端知识了,嘻嘻)。

    1、她:优点:技术强;聪明;乐观。缺点:做事不认真。

    2、我:优点:认真,上进,创造性思维强。缺点:模块化思维欠缺。

    十一、对编程思考

    结对编程有好处:

    一、可以减轻两个人的压力。

    二、相互学习、相互指正。

    三、增强两个人的关系,增强合作能力、增强代码理解能力。

    四、分工明确,增加办事效率。

    结对编程有坏处:

    一、如果交流不到位,那所做的项目将会功亏一篑。比如这次项目,因为我们前期交流没有到位,导致Web项目进行到一半,就进行不下去了。

    二、两个人各做各的,导致后期两者的项目结合比较困难。

    三、两人的分工不均匀,比如技术强的人可能做得就比较多,技术差可能就会抱大腿。

    四、要花费大量时间进行交流和解释项目,毕竟代码不好看懂。

    十二、实际PSP

     

    PSP

    任务内容

    完成时间(min)

    Planning

    计划

    60

         Estimate

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

    60

    Development

    开发

    45*60

        Analysis

        需求分析

    45

        Design Spec

        生成文档

    0

        Design Review

        设计复审

    3*60

        Coding Standard

        代码规范

    15

        Design

        具体设计

    12*60

        Coding

        具体编码

    3*8*60

        Code Review

        代码复审

    4*60

        Test

        测试

    60

    Reporting

    报告

    9*60

        Test Report

        测试报告

    0

        Size Measurement

        计算工作量

    60

       Postmortem& ProcessImprovement Plan

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

    8*60

     

     


     

    对于附加功能多语言,我们实现了两种语言的转换,其实可以通过数组实现多种语言转换,也可以通过我这种方法实现,即在生成一个界面。这种方法的好处在于简单,坏处在于代码比较多,还琐碎。

    对于附加功能多用户,我们的这个GUI界面程序,可以多人下载,多人使用,实现多用户同时在线。用户必须登陆后才能进行上传题目、出题、做题等功能的使用,还可以统计用户人数。

    参考网站:

    www.cnblogs.com/mafx/p/8536796.html  //基本的GUI语法

    https://zhidao.baidu.com/question/184288577.html  //上传文件语法

    https://www.cnblogs.com/happyzm/p/6530384.html //覆盖率教程

     

  • 相关阅读:
    Apollo配置中心环境搭建(Linux)
    SpringBoot整合Swagger2
    DevExpress ASP.NET v18.2新功能详解(四)
    UI控件Telerik UI for WinForms发布R1 2019|附下载
    DevExpress WinForms使用教程:Data Grid
    开发框架DevExtreme全新发布v18.2.6|附下载
    DevExpress ASP.NET v18.2新功能详解(三)
    .NET界面控件DevExpress全新发布v18.2.6|附下载
    DevExpress WinForms使用教程:图表控件
    VCL界面控件DevExpress VCL Controls发布v18.2.4|附下载
  • 原文地址:https://www.cnblogs.com/xia520/p/8728267.html
Copyright © 2011-2022 走看看