结对作业1
--结对编程1
源代码地址:https://git.coding.net/pyj76566/Homework.git
成员:童毅南085,潘益靖086
JavaWeb实现
a.需求分析:
我们在个人作业1中,用各种语言实现了一个命令行的四则运算小程序。进一步,本次要求把这个程序做成GUI(可以是Windows PC 上的,也可以是Mac、Linux,web,手机上的),成为一个有基本功能、一定价值的程序。在下面的功能需求中实现两个:
- 记录用户的对错总数,程序退出再启动的时候,能把以前的对错数量保存并在此基础上增量计算。
- 有计时功能,能显示用户开始答题后的消耗时间。
- 界面支持中文简体/中文繁体/英语,用户可以选择一种;
b.功能设计:
基本功能
c.设计实现:
本程序是通过java来实现的,某些类参考个人作业1,本文讲述增加的类。由于本程序是在Web上实现的,所以我们首先在component包中增加SaveAndLoad类、ResultAndAssess类;修改了User类。SaveAndLoad类主要是为了实现功能需求的第三点,。然后ResultAndAssess类主要是为了判别用户的当前输入,User类内置了新的属性和方法,分别实现新的功能。增加了三个jsp文件显示在Web上,一个Servlet控制页面流程。粗略实现用户的中英切换,用一个数组来放置不同语言,根据关系式确定语言选择;时间计算穿插在Servlet的service中,当请求到达Servlet计算开始,Servlet收到用户输入为终止,开始减去时间就是用时。
UML图:
d.代码说明:
(1)SaveandLoad类没有实例属性,只有三个静态方法, 直呼类名调用,分别是读取信息loadMessage();存储信息saveMessage();清空信息clearMessage()。由于使用文本来实现,所以我没有设置用户之分,直接读取之前所有用户输入的值的累加。
(2)ResultAndAssess类是用来实现用户把值输入文本框时,而生成的类。意思是其内部属性有boolean assess,用来判断这个值是否正确,还有String description,用来设置对和错的评语;
(3)GetTime类用于将长整型的时间转换成小时,分钟,秒的格式。
(4)userResult用来表示用户输入的值,实现数据回填。User类增加了ResultAndAssess的ArrayList,表示每一题都有一个输入和对应评价;增加了languageVersion的语言库数组,version表示其下标,根据倍数关系调用语言类型;增加了一些用户历史正确错误值等等。
(5)由于使用Web实现,所以讲述我们所新建的页面,一个是Servlet CalculatorMgr,用来控制页面提交内容时所作出的反应,内置User属性,表示当前对象;三个JSP文件,分别是index.jsp、list_problems.jsp和list_results.jsp三个页面。其中index.jsp设置生成的题数,语言,和清空文本内容的功能;list_problems.jsp是列出随机生成的算式;list_results.jsp对其判断对错给出不同的description,最后显示出正确率和历史的对错。
具体代码:
1.读取文件的代码
package com.edu.jmu.component; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.util.Scanner; public class SaveLoadMgr { public static int[] loadMessage() { File file = new File("/message.txt"); Scanner sc = null; int[] arr = new int[2]; if (file.exists()) { try { sc = new Scanner(file); if (sc.hasNextLine()) { arr[0] = sc.nextInt(); arr[1] = sc.nextInt(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { arr[0] = 0; arr[1] = 0; } return arr; } public static void clearMessage() { File file = new File("/message.txt"); PrintWriter pw = null; if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { pw = new PrintWriter(file); pw.println(0); pw.println(0); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (pw != null) pw.close(); } } public static void saveMessage(User u) { File file = new File("/message.txt"); PrintWriter pw = null; if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { pw = new PrintWriter(file); pw.println(u.historyRight); pw.println(u.historyFalse); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (pw != null) pw.close(); } } }
2.计算时间的代码
public class GetTime { static int hour; static int min; static int sec; public static String getTime(long time1,long time2){ long time =time2-time1; hour=(int) (time/3600000); min=(int) ((time-hour*3600000)/60000); sec=(int)((time-hour*3600000-min*60000)/1000); String result=String.format("%d%s%d%s%d",hour,":",min,":",sec); return result; } }
3.改正后的User类
package com.edu.jmu.component; import java.util.ArrayList; public class User { protected int historyRight = 0; protected int historyFalse = 0; protected int totalNum = 0; protected int rightNum = 0; private String runTime; private ArrayList<RandomGenerator> problems; private ArrayList<ResultsAndAssess> raa; public int version = 0;// 语言版本序号 public static final String[] languageVersion = { "right!", "false! **the correct answer is:", "Finished! The total questions are:", "and the right questions are:", ";The correct rate is:", "The history is total Right:", ",total False:", "Total run time:", "正确!", "错误! 正确答案是:", "结束!总题数为:", "而且正确题数为:", "正确率为:", "历史记录是总正确数:", ",总错误数:", "总共用时:", "正確!", "錯誤! 正確答案是:", "結束!總題數為:", "而且正確的題數為:", ";正確率為:", "歷史記錄是總正確數:", ",總錯誤數是:", "總共用時:" };// 语言库 public User() { // TODO Auto-generated constructor stub problems = new ArrayList<RandomGenerator>(); raa = new ArrayList<ResultsAndAssess>(); } public void setHistoryRight(int n) { this.historyRight = rightNum + n; } public void setHistoryFalse(int n) { this.historyFalse = (totalNum - rightNum) + n; } public String getHistory() { String history = String.format("%s%d%s%d", languageVersion[7 * version + 5], historyRight, languageVersion[7 * version + 6], historyFalse); return history; } public ArrayList<RandomGenerator> getProblems() { return problems; } public void setVersion(int version) { this.version = version; } public boolean userInputNum(String num) { problems.clear(); RandomGenerator problem; if (num.matches("[0-9]+")) { int n = Integer.parseInt(num); this.totalNum = n; for (int i = 0; i < n; i++) { problem = new RandomGenerator(); problems.add(i, problem); } return true; } return false; } public String getCorrectRate() { String end = String.format("%s %d\n %s %d\n %s %.2f%s\n", languageVersion[8 * version + 2], this.totalNum, languageVersion[5 * version + 3], this.rightNum, languageVersion[8 * version + 4], (((double) rightNum) / totalNum) * 100, "%"); rightNum = 0; return end; } public void userInputResult(String[] userResults) { raa.clear(); for (int i = 0; i < userResults.length; i++) { ResultsAndAssess temp = new ResultsAndAssess(); temp.setProblem(this.problems.get(i)); temp.setUserResult(new Fraction(userResults[i].trim())); if (temp.isAssess()) { rightNum++; temp.setDescription(languageVersion[8 * version]); } else { temp.setDescription(languageVersion[8 * version + 1]); } raa.add(i, temp); } } public ArrayList<ResultsAndAssess> getRaa() { return raa; } /** * @return the runTime */ public String getRunTime() { return runTime; } /** * @param runTime * the runTime to set */ public void setRunTime(long time1, long time2) { this.runTime = languageVersion[version * 8 + 7] + ":" + GetTime.getTime(time1, time2); } }
4.控制页面流程的Servlet
package com.edu.jmu.controller; import java.io.IOException; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.edu.jmu.component.GetTime; import com.edu.jmu.component.SaveLoadMgr; import com.edu.jmu.component.User; public class CalculatorMgr extends HttpServlet { private User user = new User(); public long startTime, beginTime; /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request * the request send by the client to the server * @param response * the response send by the server to the client * @throws ServletException * if an error occurred * @throws IOException * if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); String act = request.getParameter("act"); if ("setversion".equals(act)) { user.setVersion(Integer.parseInt(request.getParameter("version"))); request.getRequestDispatcher("./index.jsp").forward(request, response); } else if ("listGenerate".equals(act)) { String calNum = request.getParameter("calnum"); if (calNum.matches("[0-9]+")) { if (user.userInputNum(calNum)) { request.setAttribute("problemsList", user.getProblems()); startTime = System.currentTimeMillis(); request.getRequestDispatcher("./jsps/list_problems.jsp").forward(request, response); } } } else if ("listResults".equals(act)) { beginTime = System.currentTimeMillis(); user.setRunTime(startTime, beginTime); String[] userResults = request.getParameterValues("userResults"); user.userInputResult(userResults); request.setAttribute("assessList", user.getRaa()); int[] arrHistory = SaveLoadMgr.loadMessage(); user.setHistoryRight(arrHistory[0]); user.setHistoryFalse(arrHistory[1]); SaveLoadMgr.saveMessage(user); request.setAttribute("end", user.getCorrectRate()); request.setAttribute("history", user.getHistory()); request.setAttribute("runTime", user.getRunTime()); request.getRequestDispatcher("./jsps/list_results.jsp").forward(request, response); } else if ("clear".equals(act)) { SaveLoadMgr.clearMessage(); request.getRequestDispatcher("./index.jsp").forward(request, response); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
e.测试运行:
1.主界面,共有5个按钮,可单击选择语言,填入题数,生成按钮,清空文本的历史记录
2.生成后的题目
3.结果,对比不同语言版本
4.统计结果:前面是本次计算结果,第三行是历史记录,最后一行是用时。
合作和提交记录:
PSP表:
PSP2.1 | Personal Software Process Stages | Time (%) Senior Student | Time (%) |
Planning | 计划 | 45min | 50min |
· Estimate | 估计这个任务需要多少时间 | 15min | 35min |
Development | 开发 | ? | ? |
· Analysis | 需求分析 (包括学习新技术) | 1h | 1.5h |
· Design Spec | 生成设计文档 | ? | ? |
· Design Review | 设计复审 | 13min | 20min |
· Coding Standard | 代码规范 | ? | ? |
· Design | 具体设计 | 75min | 100min |
· Coding | 具体编码 | 8h | 10h |
· Code Review | 代码复审 | 1h | 1.5h |
· Test | 测试(自我测试,修改代码,提交修改) | 3h | 2.8h |
Reporting | 报告 | 40min | 45min |
· | 测试报告 | 5min | 5min |
· | 计算工作量 | 10min | 12min |
· | 并提出过程改进计划 | 5min | 5min |
小结:
JavaEE太久没写了,很多东西有点淡忘了。所以很多东西还是花了一些时间尝试Web的知识,什么Servlet,什么Jsp等等。怎么讲呢?这次作业与上次作业相比,除了增加的新类,改的最多的算是System.out.println()了,因为之前的输出都是在控制台上输出,所以想什么时候输出,就什么时候输出。但是在Web上输出就显得不一样了,很多函数一般都不是void,而是改成String。这样才能把返回值送到页面上去,而在控制台上的显示都废了。最后还是类的设计,真的是很重要,类的结构设计得好不好最基本的评判标准就是在增加新的功能的时候,是否要大幅度修改这个类的其他内容,以及其相关的其他类,感觉这方面还是得加强一下。对于结对编程的感受,总体上的感觉还是不错的。可是有时有一种浪费人力的感觉,毕竟一个人在旁边看着,虽然时不时可以交流一下还挺好。而且之前没有什么合作经历,所以你的想法有时候我的队友还不懂,还得给他讲解一番。虽然有时候在解释自己的逻辑时,会发现一些错误。所以我总体想法是,尽量有一些模块合作的经历之后,而且各自了解对方的水平之后才能更好的结对编程。