一 前言:
应该感谢我的队友,让我得到了充分锻炼的机会,以及增长了一些人生经验。
二 代码地址
https://git.coding.net/laolaf/nidayeproject.git
三 PSP
注:只是本人的计划时间和完成时间,原计划是只完成计算模块。
PSP2.1 |
任务内容 |
计划时间(min) |
实际时间 |
Planning |
计划 |
20 |
70 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
800 |
1075 |
Analysis |
需求分析 (包括学习新技术) |
40 |
50 |
Design Spec |
生成设计文档 |
20 |
20 |
Design Review |
设计复审 (和同事审核设计文档) |
20 |
20 |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
10 |
5 |
Design |
具体设计 |
40 |
50 |
Coding |
具体编码 |
800 |
800 |
Code Review |
代码复审 |
20 |
30 |
Test |
测试(自我测试,修改代码,提交修改) |
15 |
15 |
Reporting |
报告 |
20 |
40 |
Test Report |
测试报告 |
10 |
40 |
Size Measurement |
计算工作量 |
10 |
5 |
四 接口设计
1)Information Hiding:
开发软件的过程中,Information Hiding可以比较理想地完成对信息的封装,在每个模块里封装了不同的程序,达成了对每一模块内部信息的隐蔽。这样,即使不知道某模块内部,也可以对项目进行模块化的处理和分析。
2)Loose Coupling:
松耦合通过接口的方式实现各个原本有联系的模块之间的调用,比如逻辑层和业务层分开,这样可以使逻辑层出错时,不会影响到业务层。
3)
对于接口我的理解是:用于实现功能的一个没有实现功能的特殊的类,它本身是一系列操作的集合,但它是没有完成什么的,是功能函数的原型,不同的接口拼接到主类里,实现最终的功能。本项目里,gui中的guitime,guidel,Create2和Cal都可以看做接口,几个模块之间不知道它们的内部细节也是无妨的。
Command:用于命令行测试,主要内容是参数的接收以及错误抛出。
Create2:其中的Create(int n, int m1, int m2,int o)方法按照要求定制算式。
Cal:计算,在Command和gui类里可重复调用。
gui:
gui设计的时候没有严格区分出题和做题的界面。
1 guitime:计算做题时间,主界面会有计时器按钮,点击之后会再跳出一个有着“begin/开始”和“stop/结束”按钮的界面,点击之后进入倒计时。
2 guimain:简体汉语界面。它的三个按钮分别来调用guicreate,guidel,guitime,并且通过ArrayList list1和answer记录来判断做题对错的正确率。
3 guidel:作为选择界面,在该界面里有三个按钮:中文简体,中文繁体,英语,用于选择语言。
4 guiEnglish:英语界面,和汉语界面代码相似。
5 gui3:中文繁体界面。
五 性能分析
性能已经改进,Cal和Create方法在ui层和Command里重复调用。
六 单元测试
对Create2的核心代码的单元测试:
对Create2的测试的量化结果:
对guimain的测试的量化结果:
对guitime的测试的量化结果:
七 模块异常处理
异常处理有五种,分别对参数输入错误(数字变字母),对m的输入大小范围有误,m后两个参数大小颠倒,对n的输入n的大小范围出问题,参数o的范围大小有问题(应该的范围:1到10),而这些代码的写法都差不多,因此就展示抛出参数错误的代码。(这里的抛出我是直接打印在黑窗上了,直接抛出可能会被当成Command本身出了问题。)
public static void parameter1Error(String ex,int i)throws Exception{ ArrayList<String> ma= new ArrayList<String>(); ma.add("-n");ma.add("-m"); ma.add("-o");ma.add("-c"); ma.add("-b");
if(!ma.contains(ex)){ System.out.println("参数错误,重新输入"); } }
八 界面模块详细设计
设计了四个界面:guidel,guimain,guiEnglish,gui3。通过在guidel选择进入不同语言的模块,以guimain为例, guimain调用guitime,guidel,Create2,Cal的代码,通过按钮buttton-1以及它的监听类addActionListener通过把题目存到list1,把答案存到answer,最后在textArea里输出,完成记录题目和判断答案对错功能。点击“确定”按钮则开始判断,点击“生成文件”按钮则生成在root目录里的result.txt。guiEnglish和gui3同理
JButton button_1 = new JButton("提交答案"); button_1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String[] ans =textArea_1.getText().split("\n"); String strings[]=new String[list11.size()]; for(int i=0,j=list11.size();i<j;i++){ strings[i]=list11.get(i); } int count=0; for(int i = 0;i < list11.size();i++){ //answer.add(ans[i]+"");} //for(String str1:answer) //{ if(ans[i].equals(strings[i])) { print.add("对\n"); count++; } else{print.add("错\n");} } //for(int i=0,j=print.size();i<j;i++){ textArea_2.append(print+"\n"); double sum =((double)count/(double)(list11.size()))*100; lblNewLabel.setText("正确率:"+sum+"%"); // String [] print1=print; //} } });
JButton btnSubmitAnswer = new JButton("Submit answer"); btnSubmitAnswer.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String[] ans =textArea_1.getText().split("\n"); String strings[]=new String[list11.size()]; for(int i=0,j=list11.size();i<j;i++){ strings[i]=list11.get(i); } int count=0; for(int i = 0;i < list11.size();i++){ //answer.add(ans[i]+"");} //for(String str1:answer) //{ if(ans[i].equals(strings[i])) { print.add("Right\n"); count++; } else{print.add("Wrong\n");} } //for(int i=0,j=print.size();i<j;i++){ textArea_2.append(print+"\n"); double sum =((double)count/(double)(list11.size()))*100; lblNewLabel.setText("Accuracy:"+sum+"%"); // String [] print1=print; //} } }); btnSubmitAnswer.setBounds(30, 236, 124, 23); contentPane.add(btnSubmitAnswer); getContentPane().setLayout(null); JScrollPane scrollPane = new JScrollPane(); scrollPane.setBounds(20, 49, 146, 177); contentPane.add(scrollPane); scrollPane.setViewportView(textArea); textArea.setBackground(UIManager.getColor("Button.background")); textArea.setFont(new Font("MS Gothic", Font.PLAIN, 18)); JScrollPane scrollPane_1 = new JScrollPane(); scrollPane_1.setBounds(176, 49, 62, 177); contentPane.add(scrollPane_1); textArea_1.setFont(new Font("Monospaced", Font.PLAIN, 15)); scrollPane_1.setViewportView(textArea_1); JScrollPane scrollPane_2 = new JScrollPane(); scrollPane_2.setBounds(265, 49, 62, 177); contentPane.add(scrollPane_2); textArea_2.setFont(new Font("Monospaced", Font.PLAIN, 18)); scrollPane_2.setViewportView(textArea_2); textArea_2.setBackground(UIManager.getColor("Button.background")); JButton btnCallTimer = new JButton("Call timer"); btnCallTimer.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { new timer().setVisible(true); } }); btnCallTimer.setBounds(297, 238, 127, 23); contentPane.add(btnCallTimer);
guidel界面:
进入中文简体界面:
九 界面模块与计算模块对接
调用了Cal的cal方法,和Create2的create方法被调用。
十 结队过程
十一 结队优点缺点
结队编程优点:
1 两人办事按理说会有加成,效率更高。
2 两个人按理说各自分工,可以减轻压力。
结队编程缺点:
1 一个跳票的队员永远比一个单纯划水的队员可怕,你永远不知道他的马上会是几个小时或是几天,更可怕的是他把自己都忽悠信了。
2 因为对于某些技术细节的不同意见,或者是对于某些问题的理解不同,可能产生分歧,比如读这次作业的题目,我是怎么也不觉得可以做一个微信小程序。
3 不同人的性格未必相同。性格比较急躁的人可能不赞同deadline几小时前赶一下界面模块的。
队员优缺点:
张舒凯:
优点:花的时间比较多。
缺点:人傻,不知道见微知著。脾气暴躁,过于push。编程能力欠佳,功能实现得太慢
葛金星:
优点:脾气温和。性格沉稳。
缺点:想法太多。