• 软件工程第三周 结对编程


    一、链接

    二、代码

    1. 需求分析:

    • 现有代码实现简单的加减乘除算术出题运算,提供三种语言的切换,有复习,计时,判断正确率的功能
    • 对现有代码进行分析,发现如下问题:
      • (1)复习功能不完善,复习的按钮在初始界面,点击之后跳回初始界面,无法再进行下一步的点击
      • (2)初始界面较为粗糙,界面出现在屏幕左上角,用起来很难受。语言切换非常不明显,整体布局也不太符合人体习惯
      • (3)文档作用不明显,对于源代码的分析了解基本是我们从代码直接进行分析的。变量名设置比较随意,一些重要框架没有说清楚。
      • (4)因为软件面向的对象定为小学生,所以两个数的加减乘除的数取值在100以内,混合运算的取值则在10以内,相对符合现在学生情况。
      • (5)原本的“再一次”和“复习”功能存在bug,重新进行选择不会读取用户再一次输入的题目数量。另外“复习”部分只会弹出当此的题目,而不会从错题库中随机读取,比较不符合练习题的规范。
      • (6)未对重复题目的出现进行判断
    • 进行优化的部分:
      • 更改初始界面,初始界面增加“复习”部分,语言选择改为菜单栏选项。在不对界面框架做大的更改的情况下,增加按键,修改布局,界面显示在电脑屏幕正中间。
      • 优化界面显示和跳转,在第二个界面加上“结束”部分,优化用户手感问题。同时添加跳出所有正确答案功能,在希望结束的时候不用去点击右上角的,而是可以自己选择结束暂停。
      • 新增平方和括号的计算,并在原来只针对分数的加减乘除的计算题扩大范围。
      • 关于计算部分的优化,经过一定的搜索,现在的小学生混合运算主要偏向于能够快速化简的分数除法,我们的代码还暂时无法达到这个要求,这个也需要进一步的升级。
      • 优化上述第五点的问题,实现了一个较为正常的“复习”功能和“再一次”的选择
      • 优化上述第六点的问题,解决了对于历史题目重复出题的bug。但是对于一开始随机的出题的重复率判断,有尝试解决,结果发现了源代码更大的bug。在解决重复出题的过程中,这些bug都一一解决了,然而这个最开始的问题......还是凉了。详情见队友博客。

    2. 程序设计:

    2.1 码云提交记录

    2.2 类图部分


    2.3 覆盖率测试

    其中覆盖率偏低的几个类,都存在或多或少的测试局限问题,比如下图,分母等于0的概率实在太低,太难触发

    这部分是关于做题时长的测试,当做题时间过长才会出现

    还有这里是对于历史存储的问题,因为有原文件的存在,所以没有触发

    另外大部分的问题都在于代码的异常捕获,这个......真的挺难触发的

    2.4 逻辑图部分,红色的表示我们做了优化或是新增的功能

    2.5 内存分析优化



    3. 代码展示:

    public String fra_operation(){	//复杂运算
    		
    		this.t1 = new Random().nextInt(10)%(10-1+1) + 1;
    		this.t2 = new Random().nextInt(10)%(10-2+1) + 2;
    		this.t3 = new Random().nextInt(10)%(10-1+1) + 1;
    		this.t4 = new Random().nextInt(10)%(10-2+1) + 2;
    		int fz=1,fm=t2*t4;	//分子,分母
    		
    		if(k==1)//除法
    		{
    			if(t2<t1||t4<t3||t2%t1==0||t4%t3==0)
    			{
    				astr=fra_operation();
    				return astr;
    			}		
    			if(k1==0)
    			{
    				fz=t1*t4+t2*t3;
    			}
    			
    			if(k1==1){
    				fz=t1*t4-t2*t3;
    				if(fz==0)
    				{
    					return astr=("0");
    				}
    			}
    			
    			if(k1==2)
    				fz=t1*t3;
    			if(k1==3)
    			{
    				fz=t1*t4;
    				fm=t2*t3;
    			}
    			int f=common_divisor(fm,fz);
    		
    			if(f>0){
    				fm=fm/f;
    				fz=fz/f;
    			}
    			if(f<0){
    				fm=-fm/f;
    				fz=-fz/f;
    			}
    			astr = (fz+"/"+fm);
    			if(astr.equals("1/1")) astr="1";
    			if(fm==1) astr = (fz+"");	
    		}
    		else if(k==0)//乘法
    		{
    			fm=1;
    			if(k1==0)//加法
    			{
    				if(k2==3)
    					fz=t1*(t2+t3)*t4;
    				else fz=t1*t2+t3*t4;
    			}
    			if(k1==1)//减法
    			{
    				if(k2==3)
    					fz=t1*(t2-t3)*t4;
    				else fz=t1*t2-t3*t4;
    			}
    			if(k1==2)//乘法
    			{
    				fz=t1*t2*t3*t4;	
    			}	
    			if(k1==3)//除法
    			{
    
    				if(k2==1)//t1*t2/(t3*t4)
    				{
    					if(t1==0||t2==0) return astr=("0");
    					else if(t3==0||t4==0)
    					{
    						astr=fra_operation();
    						return astr;						
    					}
    					else{
    						fz=t1*t2;
    						fm=t3*t4;
    					}
    				}
    				
    				else	//if(k2==0) t1*t2/t3*t4
    				{
    					if(t3==0)
    					{
    						astr=fra_operation();
    						return astr;
    					}
    					else if(t1==0||t2==0||t4==0) return astr=("0");
    					else{
    						fz=t1*t2*t4;
    						fm=t3;	
    					}
    				}			
    				
    				int f=common_divisor(fm,fz);
    						
    				if(f>0){
    					fm=fm/f;
    					fz=fz/f;
    				}
    				if(f<0){
    					fm=-fm/f;
    					fz=-fz/f;
    				}
    				astr = (fz+"/"+fm);
    			}	
    			if(k1!=3) astr=fz+"";
    			if(fm==1) astr = (fz+"");
    		}
    		if(astr.equals("1/1")) astr="1";	//修改 bug	1
    		return astr;	
    	}
    	
    
    	//复习键
        private void Re_ButtonMouseClicked(MouseEvent evt) throws FileNotFoundException { 
        	if(Number.getText().matches("\d*")){
        		Frame.hh.i = Integer.parseInt(Number.getText());	//获取输入题数
        		if(Frame.hh.i<=10&&Frame.hh.i>=1)
        		{  			
    	        	Frame.hs.Histroy_read();
    	            for(int a=0;a<Frame.hh.i;a++){   	
    	            	int b = new Random().nextInt(Frame.hs.astrlist.size()-1);
    	            	Frame.hh.Answer.set(a, Frame.hs.astrlist.get(b));
    	            	Frame.hh.Qusetion.set(a, Frame.hs.qstrlist.get(b));
    	            	List<Integer> count=new ArrayList<Integer>(Arrays.asList(list));
    	            	if(count.contains(b)) a--;
    	            	else list[a]=b;	
    	            }
    	            for(int a=0;a<(10-Frame.hh.i);a++){
    	            	Frame.hh.Answer.set(a+Frame.hh.i, "");
    	            	Frame.hh.Qusetion.set(a+Frame.hh.i, "");
    	               }
    	        }
        			
    	        java.awt.EventQueue.invokeLater(new Runnable() {
    	              public void run() {
    	                   new Frame(true).setVisible(true);
    	               }
    	           });	
    	        	this.dispose();
    	        	i++;
    	        	try {
    	    			Frame.hs.History_num();
    	    		} catch (FileNotFoundException e) {
    	    			e.printStackTrace();
    	    		}
        		}	
        } 
    
    
    public class QA_List {
    
    	public static int i=0;
    	public static List<String> Qusetion;
    	public static List<String> Answer;
    	public QA_List(){	
    		Qusetion=new ArrayList<String>();
    		Answer=new ArrayList<String>();
    		
    		for(int a=0;a<i;a++)
    	    {			
    			Runtime.getRuntime().gc();		
    	        boolean flag= new Random().nextBoolean();        
    	        Arithmetic hh = new Arithmetic(flag);	        
    	        String int_str = hh.int_operation();
    	        String fra_str = hh.fra_operation();	        
    	        if(flag==true)	//
    	        {
    	        	Answer.add(int_str);
    	        	Qusetion.add(hh.toString());
    	        }	        	
    	        if(flag==false)	//
    	        {
    	        	Answer.add(fra_str);
    	        	Qusetion.add(hh.toString());
    	        }
    	        System.out.println(Answer.get(a)+"   "+Qusetion.get(a));
    	    }		
         for(int a=0;a<(10-i);a++){
         	Answer.add("");
         	Qusetion.add("");
         }
    	}	 
    }
    
    

    4. 程序运行:

    • 由于在开发过程中我不做结果正确率的测试,所以截图里的正确率偏低。






    5. 小结感受:

    • 先说一点,,,我认为开发工具的统一十分重要。就比如我们使用的源代码的图形界面时在netbeans的环境下直接拖选的,netbeans会生成大量的无用代码以及框架比较难以更改。在此基础上,手动修改的难度就比较大。
    • 回到正题,我认为结对编程可以带来1+1>2的效果。首先,每个人擅长的方向不一样,一个软件的开发是需要各方各面的功能的。一个人很难做到面面精通,所以通过合作,可以让开发效果,从技术水平上来说达到最好。
    • 另外,一个人的思路总是狭窄的。比起两个人一起,一个人更容易钻牛角尖。比如我在调试一个界面的位置问题时,总是没法调整到想要的地方,也查不到能用的函数,队友换了个关键词一下子就查到了。我简直怀疑她和我用的不是同一个百度。就,总的来说,很多时候有个能讨论的人,在开发的时候不会太过于局限,不管是思路还是设计都会开阔很多。
    • 在原本的代码框架上进行修改相对困难,但是好处是基础都有,只要优化就行了,不过也有不少功能需要把之前的方法推翻重来。
    • 还有一点就是,结对编程对于水平稍微弱一点的人来说,其实是很好的。分工合作愉快
    • 队友身体不舒服一周了,挺艰难的
    • 以及......在思考的时候被打断,是真的需要全部重新思考的......我们深刻体会了这个道理


    (亲身体验,真的)

    三、 结对编程照片

    由于两人非同宿舍,图书馆讨论不方便。再由于我们这一次的编程周期偏长,基本用了一周半的时间,时间也不能完全对的上,所以我们都是在QQ上互相交流和讨论的。比如我在外面的时候,她在编程,遇到的问题和一些地方都会提出来一起讨论。所以要两人非摆拍的一起讨论的照片......那是没有的。我们只提供得了聊天记录截图......(内容有点多......)


    以上是我们针对一个按钮的新功能的测试阶段的部分讨论

    四、 PSP部分

  • 相关阅读:
    利用Multipeer Connectivity框架进行WiFi传输
    iOS 8创建交互式通知
    iOS开发网络篇—文件的上传
    iOS开发网络篇—发送GET和POST请求(使用NSURLSession)
    iOS之深入了解控制器View的加载
    工厂模式三部曲:工厂方法模式
    iOS web与js的简单交互
    精心整理的十个必须要知道CSS+DIV技巧
    [JQuery代码]超酷鼠标滑过背景高亮效果
    10个可以直接拿来用的JQuery代码片段
  • 原文地址:https://www.cnblogs.com/ycll/p/8615244.html
Copyright © 2020-2023  润新知