Coding 地址:https://git.coding.net/jiapwy/newfouroperation.git

队友:周紫伊

队友博客地址:

http://www.cnblogs.com/zhouzy539/p/8776238.html

 

 

一、写在前面

其实这次作业对我而言难度很大,本人花费了很大的功夫才基本实现功能,所以十分感谢我的队友在这次结对编程中对我的帮助,通过这次作业,深深地意识到了自己的不足,希望接下来能再接再厉,争取学到更多知识和技能。

 

 

二、PSP

PSP

任务内容

计划时间(min)

完成时间(min)

Planning

计划

30

20

     Estimate

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

30

50

Development

开发

1100

2900

    Analysis

    需求分析

60*5

40

    Design Spec

    生成文档

30

30

    Design Review

    设计复审

10

2

    Coding Standard

    代码规范

5

20

    Design

    具体设计

60

60

    Coding

    具体编码

600

1200

    Code Review

    代码复审

20

20

    Test

    测试

30

1200

Reporting

报告

40

180

    Test Report

    测试报告

30

120

    Size Measurement

    计算工作量

10

25

   Postmortem& ProcessImprovement Plan

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

5*60

4*60

 

 

 

三、接口的设计

 

对于面向对象的程序设计而言,信息隐藏是一种重要的软件开发手段,它与对象的封装(encapsulation)与模块化(modularity)密切相关。在我看来,信息隐藏使得一个类把复杂的、敏感的、一旦被外界捕获可能会引起不良后果的内容封装在自身内部,这个类以外的代码得不到此类信息(通过反射等手段可能对得到),以提高程序的安全性与健壮性。

而要设计接口,就要从最根本上进行了解,下面即是一些基本概念:

Interface Design是面向接口编程是软件工程领域常用的设计手段

Loose Coupling是基于面向接口编程,松耦合度是接口设计的目的,接口设计是松耦合度的实现手段

nformation Hiding是信息隐藏指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是不可访问的。

在了解过这些后,我们便可以进行更顺畅的接口设计。

 

关于interface design与loose coupling

查阅了很多资料,也看了很多同学博客中的分享,我非常同意‘这两个概念是相辅相成的,后者是前者的目的,前者是后者的实现手段。’这句话。

面向接口编程是软件工程领域常用的设计手段,我们在这次结对编程中也不例外,一开始其实并不是很懂得其中的妙处,在不断的尝试中终于领悟到了一点道理。

面向接口的程序设计思想是一种十分有效的手段。做一个项目,只要通过面向于数据组提供的一整套接口进行编程,同时,很多其他工作可以并行进行,这样,不需要等待一个模块的完成就可以预先“使用”这个模块,极大提高了编程的效率和速度。

 

四、计算模块接口的设计与实现功能

在经过小组的商讨之后,我们的计算模块接口由两个类组成

Main类:模块的主类,负责接收命令行的参数并启动程序以及调用函数

test类:生成符合命令行参数要求的题目,包括加减乘除等运算

计算类中的方法有:

num方法:产生随机数,并且产生要求的算式

calculator方法:负责筛选运算过程中符合要求的式子,并计算正确答案

nibolan方法:中缀表达式转后追表达式 。

 

 

 

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

见下图

 

 

 

 

 

 

 

 

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

 测试输入是有错误的

 

 测试分母为0

 

代码覆盖率

 

 

 

 

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

 

我们共设计了四种异常处理,分别是出题数量异常处理,数值左边界异常处理,数值右边界异常处理和运算符数量异常处理。

 

1)出题数量异常处理

 

当用户输入的出题数量的数值不在范围内时,提醒用户当前输入的数值不合法,要求用户重新输入。

 

try {

 

n1 = Integer.parseInt(n.getText());

 

if (n1 <= 0 || n1 > 10000) {

 

n.setText("请输入合法参数");

 

return;

 

}

 

flag0 = 1;

 

} catch (Exception a) {

 

n.setText("格式不正确,请重新填写!");

 

}

 

 

 

 

 

 

 

2)数值左边界异常处理

 

    当用户输入的出题数值左边界不在范围内时,提醒用户当前输入的数值不合法,要求用户重新输入。

 

try {

 

m11 = Integer.parseInt(m1.getText());

 

if (m11 <= 0 || m11 > 100) {

 

m1.setText("请输入合法参数");

 

return;

 

}

 

flag1 = 1;

 

} catch (Exception a) {

 

m1.setText("格式不合法,请重新填写!");

 

}

 

 

 

 

3)数值右边界异常处理

 

    当用户输入的出题数值右边界不在[50,1000]范围内时,提醒用户当前输入的数值不合法,要求用户重新输入。

 

代码展示:

 

try {

 

m22 = Integer.parseInt(m2.getText());

 

if (m22 < 50 || m22 > 1000) {

 

m2.setText("请输入合法参数");

 

return;

 

}

 

flag2 = 1;

 

} catch (Exception a) {

 

m2.setText("格式不合法,请重新填写!");

 

}

 

 

 

 

4)运算符数量异常处理

 

当用户输入的运算符数量不在范围内时,提醒用户当前输入的数值不合法,要求用户重新输入。

 

try {

 

o1 = Integer.parseInt(o.getText());

 

if (o1 <= 0 || o1 > 10) {

 

o.setText("请输入合法参数");

 

return;

 

}

 

flag3 = 1;

 

} catch (Exception a) {

 

o.setText("格式不合法,请重新填写!");

 

}

 

 

 

 

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

1)欢迎界面

 在开始时,我们对GUI的理解十分少,对基本的语句功能实现都非常困难,例如GUI的Button事件都不能实现,设计也十分不美观,下面是最开始的失败界面。

 

在尝试了很多之后,通过不断的学习,我们改进了界面,终于做的可以看了,并且实现了一部分功能,下面附上代码和图片。

 

 

 

import java.awt.*;  
import java.awt.event.*;  
import javax.swing.*;  
import javax.swing.event.*;  
  
  
public class Main  
{     
    public static JTextField jtf =new JTextField(5); //文本框
    public Main()  
    {   
        JMenuBar jmb=new JMenuBar();  //菜单栏
        JFrame jf=new JFrame();       //窗口
        final JLabel jlb =new JLabel();     //标签
        final JButton jb =new JButton();      //按钮
        JPanel jp =new JPanel();        //容器
        JPanel jp1 =new JPanel();       
        jlb.setText("出题数量");
        jtf.getText();
        jb.setText("生成题目  ");
         
        
        
        jf.setLayout(new BorderLayout());  //布局
        jf.setSize(500, 400);  
        jf.setTitle("欢迎使用四则运算界面");
        JMenu jm=new JMenu("语言选择");    //菜单
        JMenuItem mi1=new JMenuItem("中文");  //菜单项
        JMenuItem mi2=new JMenuItem(""); 
        JMenuItem mi3=new JMenuItem("英文"); //实现选择语言功能
        jm.add(mi1);
        jm.add(mi2);
        jm.add(mi3);          
        jmb.add(jm);
        jp.add(jlb);
        jp.add(jtf);
        jp1.add(jb);
       
        ImageIcon img = new ImageIcon("src/test2/2PAA~5DRU_W_ZJG]3");
        jf.add(jp,BorderLayout.NORTH);
        jf.add(jp1,BorderLayout.CENTER);
        jf.setJMenuBar(jmb);  
        jf.setVisible(true); 
        
        mi1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                jlb.setText("出题数量");
                jtf.getText();
                jb.setText("生成题目");                
            }
        });
        mi2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                jlb.setText("出题数量");
                jtf.getText();
                jb.setText("go");                
            }
        });
        mi3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                jlb.setText("please input the number of questions you want");
                jtf.getText();
                jb.setText("generate tests");      //完成英文版          
            }
        });
        jb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                methodjb();                
            }
        });
    }  //完成最初界面
    public static void methodjb(){
        new MainFrame(Integer.parseInt(jtf.getText()));
    }
    public static void main(String args[]) {  
            new Main();   //主函数调用
    }  
}  

 

(2)答题页面

当填写完出题数量后,再点击生成题目时,会出现另一个界面,页面包括所有生成的题目,以及结果的输入处,包括计时功能的完成,而语言选择项仍然存在,最后是生成题目按钮,当你点击按钮,运算的结果,时间就会传递给后台,而接下来的页面会进行相应判断的显示。下面附上对应代码。

 

 for(int i=0;i<n;i++)
                {

                    JLabel jb=new JLabel();                   
                    jb2[i]=new JLabel();
                    
                    jb.setText(strarr[3*i]+strarr[3*i+1]);
                    if(strarr[3*i+1].equals(strarr[3*i+2]))
                    {
                        jb2[i].setText("正确");
                        mi1.addActionListener(new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                for(int i=0;i<n;i++)
                                {
                                if(jb2[i].getText().equals("正确")||jb2[i].getText().equals("正确")||jb2[i].getText().equals("right"))
                                    jb2[i].setText("正确");
                                else
                                    jb2[i].setText("错误,答案是:"+strarr[3*i+2]);
                                }
                            }
                        });
                        mi2.addActionListener(new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                for(int i=0;i<n;i++)
                                {
                                if(jb2[i].getText().equals("正确")||jb2[i].getText().equals("正确")||jb2[i].getText().equals("right"))
                                    jb2[i].setText("正确");
                                else
                                    jb2[i].setText("错误,答案是"+strarr[3*i+2]);
                                }
                            }
                        });
                        mi3.addActionListener(new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                for(int i=0;i<n;i++)
                                {
                                if(jb2[i].getText().equals("正确")||jb2[i].getText().equals("正确")||jb2[i].getText().equals("right"))
                                    jb2[i].setText("right");
                                else
                                    jb2[i].setText("wrong,the answer is :"+strarr[3*i+2]);
                                
                                }
                            }
                        });//计算正确答案
                    }
                    else
                    {
                        jb2[i].setText("错误,答案是:"+strarr[3*i+2]);
                                cuowu+=1;
                        
                    }
                    jp.add(jb);
                    jp.add(jb2[i]);
                }//出现错误答案

 

 

 

(3)最终页面

当你在题目页面点击了提交按钮,你的题目和答案会一起提交到后台,后台的计时器会停止计时,并且后台会对你的题目进行分析判断,最后提交给你一份答案页面,以及你答题所用的时间信息,还有你错误的题目的正确答案下面附上图片和代码。

 

 

     JPanel jp1=new JPanel();
                
                mi1.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        jbt.setText("记录");
                    }
                });
                mi2.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        jbt.setText("记录");
                    }
                });
                mi3.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        jbt.setText("record");
                    }
                });//产生记录
                jp1.add(jbt);
                jp.add(jp1);
                final JLabel lbl1 = new JLabel();
                lbl1.setText("用时  :"+lbl.getText());
                mi1.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        lbl1.setText("用时:"+lbl.getText());
                    }
                });
                mi2.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        lbl1.setText("用时:"+lbl.getText());
                    }
                });
                mi3.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        lbl1.setText("time :"+lbl.getText());
                    }
                });
                jp.add(lbl1);
                jf.add(jp);
            }
        });//累计用时的方法
        jb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {              
            }
        });
    }  
    public static void main(String args[]) {  
            new Main();   
    }  
}  //调用函数

 

(4)整体实现过程

 

 

 

 

 

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

在思考之后,我们放弃了网页,选择了了GUI类,即使用了图形用户界面来进行UI模块的设计,至于这些各种不同UI模块之间的对接,则是通过事件监听器接口来实现的。

参数传递功能

String n = JOptionPane.showInputDialog(

                                frame,

                                "输入题目的数量(1-1000):"

                        );

                        String m = JOptionPane.showInputDialog(

                                frame,

                                "输入数值范围(1-10000):"

                        );

                        String z = JOptionPane.showInputDialog(

                                frame,

                                "输入符号数量(1-10):"

                        );

 

部分页面截图

 

 

 

 

 十、结对过程

 因为工作量较大,我和我的结对小伙伴一早就定下了分工,虽然中间经历了一个小假期,但是我们也不时都在为这个作业而思考,在作业过程中我们遇到了很多困难,有时候一筹莫展,但好在我们一直在努力寻找解决方法,而且沟通良好,两人之间不存在任何嫌隙,最终也都如愿以偿得到了让我们比较满意的结果。下面附上我们的结对照片。

 

 

十一、结对编程优缺点

 

优点:在结对编程中,深刻地体会到了1+1>2的含义,与个人单独编码相比,结对更加的高效,而代码变得更加有质量。当你在敲代码时,有另外一个人在不断提醒监督着你,这让自己克制了一些单独编码时不免会犯的错误,比如惰性和一些基础性的错误,同样,两个人的共进退让我们充满斗志,突破了困难局限,最终完成一项让我们自己满意的项目。

缺点:对于结对编程来说,沟通磨合是非常重要的,一旦没有有效的沟通,那结对编程便很难进行下去,而沟通一直是人与人之间的难题,我想这也算是结对编程所不可避免的缺点吧。另外,每个人编程都有自己的习惯和风格,所以当两个人在一起工作时,难免会产生矛盾就和摩擦,这也是不太容易解决的问题。

 各人优缺点:

 

 

周紫伊

胡雅馨

优点

认真细心,有耐心

 

积极,上进,善于学习,平易近人

 

缺点

基础知识薄弱,不善于沟通交流

缺点:基础知识不扎实,偶尔懒散

 

 

 

 

十二、最后

这次作业完成的相当费力,也深刻地感觉到了无力,由此发现自己还有很多薄弱的地方,通过这次学习,也学到了不少东西,希望能再接再厉,不断进步。