zoukankan      html  css  js  c++  java
  • 基于GUI的小学生四则运算系统

    前言:首先在此感谢我的结对搭档,没有她的帮助和引导绝不会有现在的项目。很高兴和她一起结对完成这个项目。搭档真的是棒棒哒!

    一、Coding.Net项目地址 https://git.coding.net/day_light/GUIszysLL.git

    二、PSP计划表格

    PSP

    任务内容

    计划需要时间(min)

    Planning

    计划

    60

    Estimate

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

    60

    Development

    开发

    32*60+50

    Analysis

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

    2*60

    Design Spec

    生成设计文档

    20

    Design Review

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

    10

    Coding Standard

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

    20

    Design

    具体设计

    3*60

    Coding

    具体编码

    24*60

    Code Review

    代码复审

    60

    Test

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

    2*60

    Reporting

    报告

    60

    Test Report

    测试报告

    30

    Size Measurement

    计算工作量

    10

    Postmortem & Process Improvement Plan

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

    20

    三、Information Hiding, Interface Design, Loose Coupling方法对接口进行设计

    Information Hiding即信息隐藏,指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是不可访问的。也就是说,我们在编程的时候只需调用有关的方法,函数,知道它是干什么的而无需知道它是怎么具体实现的。

    Interface Design,即接口设计,我的理解就是将模块化进行到底吧。通过接口可以实现不相关类的相同行为,而不需要了解对象所对应的类。从程序角度,简单理解,接口就是函数声明,类就是函数实现。需要注意的是同一个声明可能有很多种实现。我们在设计过程中也体会到了接口的好处。

    Loose Coupling即松耦合耦合程度越高,模块与模块之间的联系性就更高,系统的灵活性就越低,报错率就更高。我们在设计过程中尽可能地让算式的产生和计算,优先级判断相互独立,但是我们目前使用的算法还可能出现性能方面的不稳定性(一般出现在加减乘除带括号运算的情况中)。

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

    我们的项目一共有两个类,Command类与Lib2类,Command类是主类包含主函数,负责接收从命令行输入的参数。Lib2类一共有4个计算函数compute1,compute2,compute3,compute4。分别对应加减运算,加减乘除运算,加减带括号运算,加减乘除带括号运算。对应的进行算式的产生和运算。

    流程图如下:

     

    我们的代码并没有什么独到的地方,值得一提的或许是我们的代码不是很精但还算的上是清晰易懂吧。

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

    在计算模块性能的改进过程中,我们花费了将近一天的时间,有效时间大约为8小时左右。最后的实现方法是:当遇到除法的时候,我们尽可能随机产生被除数的因数,以减少代码随机生成的无效循环。当遇到乘法的时候,尽可能地减少乘数的大小,以保证在不超出用户范围的同时,可以产生较多的式子,来满足用户的需求,同时提高代码覆盖率。我们消耗最大的就是Lib2类,即算式生成,与计算模块。

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

    在进行单元测试的时候,我们打算尽可能扩大参数的选择范围,尽可能的多出题目,多增加运算符号以测试程序的可用性。

    以下是对计算类Lib2中四个运算函数compute1,compute2,compute3,compute4的单元测试代码及其覆盖率:

    import static org.junit.Assert.*;
     
     import org.junit.Test;
     
     public class test {
         Lib2 lib = new Lib2();
         @Test
         public void test() {
             lib.compute1(1000, 10, 50, 1000);
             lib.compute2(1000, 10, 50, 1000);
             lib.compute3(1000, 10, 50, 1000);
             lib.compute4(1000, 10, 50, 1000);
             
         }
     
     }

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

    样例1:n为非法字符(字母,符号等,这里以字母为例)。 

    @Test
    public void testn1command() 
    { String[] args
    ={"-n","e","-m","1","100"}; Command.main(args); }

    样例2:n超出预计范围(n小于1或大于10000,这里以-9为例)。

    @Test
    public void testn2command() 
    { String[] args
    ={"-n","-9","-m","1","100"}; Command.main(args); }

     样例3:m1,m2超出预计范围(m1大于m2或者m1小于1大于100或者m2小于50大于1000,这里以m1为-8,m2为40为例)。

    @Test
    public void testm1command() 
    { String[] args
    ={"-n","10","-m","-8","40"}; Command.main(args); }

     样例4:m为非法字符(字母,符号等,这里以字母为例)。

    @Test
    public void testm2command()
    { String[] args
    ={"-n","10","-m","8","e"}; Command.main(args); }

     样例5:m,n不存在。

    @Test
    public void testmncommand() 
    { String[] args
    ={}; Command.main(args); }

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

    我们的项目是用GUI来实现的用户界面,大体思路如下:

     

    以出题界面部分代码展示为例:

    public GUI() {
            mybutton=new ActionFrame().getButton();
            JPanel p1 = new JPanel(new GridLayout(0, 2));
            JPanel p3 = new JPanel(new GridLayout(0, 2));
            p1.add(new JLabel("请输入题目数 "));
            p1.add(n);
            p1.add(new JLabel("运算符个数上限"));
            p1.add(o);
            p1.add(new JLabel("数值范围下界 "));
            p1.add(m1);
            p1.add(new JLabel("数值范围上界 "));
            p1.add(m2);
            p3.add(A);
            p3.add(B);
            //p3.add(mybutton);
            JPanel p2 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
            p2.add(mybutton);
            
            p2.add(jbtBeginCompute);
            add(p1, BorderLayout.CENTER);
            add(p2, BorderLayout.SOUTH);
            add(p3, BorderLayout.EAST);
            ButtonListener listener = new ButtonListener();
            jbtBeginCompute.addActionListener(listener);
            A.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    c = 1; // 是否有乘除
                }
            });
            B.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    b = 1; // 是否有括号
                }
            });
        }

     

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

    UI在上一个模块中已经展示过了,下面说一说两模块对接的问题。我们在设计过程中通过定制题目界面接受用户选择的参数,再通过用户参数的限制选择相应的生成算式的模式,然后是调用计算模块。用户的输入和系统的算式生成与计算是两个相互独立的系统,互不干扰。

    界面展示:

    定制出题

    错题库:

    上传题目:

    命令行测试:

    十、结对照片

    十一、结对编程的优点和缺点。

    结对编程的优点:

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

    2)两个程序员之间可以相互教对方,进行优劣势的互补。

    结对编程的缺点:

    1)两个人在一起工作可能会出现工作精力不能集中的情况。程序员可能会交谈一些与工作无关的事情,反而分散注意力,导致效率比单人更为低下。

    2)有时候,程序员们会对一个问题各执己见(代码风格可能会是引发技术人员口水战的地方),争吵不休,反而产生重大内耗。

    搭档的优缺点:温柔,超级好说话沟通无障碍,彼此都能懂。可以实现互帮互助,一起学习,有时候,会对一个问题很坚持,缺少变通性。

    我的优缺点:细致,耐心,计划性强,但偶尔会开小差。

    十二、PSP实际表格

    PSP

    任务内容

    实际需要时间(min)

    Planning

    计划

    60

    Estimate

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

    60

    Development

    开发

    2738

    Analysis

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

    5*60

    Design Spec

    生成设计文档

    20

    Design Review

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

    8

    Coding Standard

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

    10

    Design

    具体设计

    300

    Coding

    具体编码

    1800

    Code Review

    代码复审

    120

    Test

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

    180

    Reporting

    报告

    82

    Test Report

    测试报告

    60

    Size Measurement

    计算工作量

    7

    Postmortem & Process Improvement Plan

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

    15

    十三、总结

    这个项目对我来说,难度不小,甚至可以说是很大。我接触到了很多新的东西,比如说,怎么进行单元测试,怎么做效能分析(虽然现在还是有点懵),怎么看代码覆盖率,性能的改进等等。这让我明白了编程不仅仅是按要求敲完代码就好了的事情。

    什么是好的代码?我想好的代码就是尽可能满足用户要求的,代码覆盖率高的,系统性能好的,效能合理的,通俗易懂的吧。我们为什么要敲好的代码?因为我们需要好的代码。为什么需要?因为提升了性能,就是增大了系统在极端情况下的可用性,减少出现bug的概率,给用户更好的使用体验,并且还可以提升自己项目的核心竞争力。同时,通俗易懂的代码可以减少因熟悉代码而浪费的不必要的时间,提高整体的效率。

    结对,是让两个人的思想,方法,习惯,性格进行的碰撞,这是一场美好的体验,最后还是要感谢我的搭档和帮助过我们的小哥哥小姐姐们。

  • 相关阅读:
    day 28 客户端服务端架构介绍,互联网协议,互联网协议补充,三次握手与四次挥手
    day25 单例模式实现方法一 单例模式实现方法二
    day24 反射/定制__str__方法控制对象的打印格式/定制__del__方法回收系统资源/元类介绍以及默认元类type创造类的过程/自定义元类控制类的创建过程/自定义元类控制类的调用过程
    day 23 封装之如何隐藏、封装之隐藏属性的底层原理、封装的真正意义、property特性、绑定方法与非绑定方法
    day22 组合、菱形继承问题、C3算法与mro介绍、在子类派生的新方法中重用父类功能的两种方式、super()严格以来继承关系、多态与鸭子类型
    day21 对象定制自己独有的属性/属性查找/绑定方法/小结/继承介绍/继承与派生
    day19 正泽表达式,sys模块,打印进度条,subprocess模块
    day18 logging模块的补充/jason序列化与反序列化/json补充/pickle序列化与反序列化/time模块/datetime模块/random模块/os模块
    day17 包的使用 logging模块的基本用法
    day16 面向过程编程/模块介绍/import导入模块/ from...import导入模块/循环导入问题/模块的搜索路径/区分python文件的两种用途/软件开发的目录规范
  • 原文地址:https://www.cnblogs.com/2016SE_NENU/p/8761426.html
Copyright © 2011-2022 走看看