结对编程之实战

  结对编程?这是什么鬼?赶快google了一下,根据维基百科给出的定义,结对编程(英语:Pair programming)是一种敏捷软件开发的方法,两个程序员在一个计算机上共同工做。 一我的输入代码,而另外一我的审查他输入的每一行代码。 输入代码的人称做驾驶员,审查代码的人称做观察员(或导航员)。 两个程序员常常互换角色。其实说白了就是两我的轮流操做一个机器(人闲机不闲),一人编码,一人审查。体现了1+1>2的思想。废话少说,进入正题。前端

结对伙伴:李星明java

代码托管地址:Codingc++

1、题目选择

做业博客地址:结对编程第2次做业程序员

通过和结对伙伴商量,此次咱们选择题目一做为结对编程的实战项目。算法

  • 题目1:编程

    • 咱们在刚开始上课的时候介绍过一个小学四则运算自动生成程序的例子,请实现它,要求:
      • 可以自动生成四则运算练习题
      • 能够定制题目数量
      • 用户能够选择运算符
      • 用户设置最大数(如十之内、百之内等)
      • 用户选择是否有括号、是否有小数
      • 用户选择输出方式(如输出到文件、打印机等)
      • 最好能提供图形用户界面(根据本身能力选作,以完成上述功能为主)

2、准备工做

1.软件建模和设计

闲话少说,先贴上软件系统图以下:


软件系统图详解:图中虽然写得是mvc,其实这个设计更接近于mvp的模式。在V层采起java的编程语言,CM层采起的是C语言编程
设计过程:在设计的时候是咱们一块儿本着下降耦合性、模块化、易于维护和可扩展的原则下进行设计和建模,最终选择了上图结构;这样的话,M层都是最基本的模块(戏称为“原子划分”),尤为是Random;C层只依赖于M层,只有一个模块,下降了耦合性;V层依赖于C层;其中M层的功能只暴露给C层,M层的Random模块只暴露给M层的其余模块。这样的话就知足了功能单一和下降耦合性的原则。为了完善题目需求,添加了去重和求值模块后端

  软件建模完成后,咱们又一块儿讨论了其中M层几个模块的具体实现方法:数组

  • 为了方便操做和传送数据,咱们对整个运算表达式进行了数字化。例如:用8,4,2,1分别表明+ - * /,用最大数和最大数加1表明左括号和右括号
  • 在对运算符组合的处理中用到的用到了位操做
  • 求值模块用到了算符优先表和栈
  • 运算表达式存储结构是包含二维浮点数数组的结构体
  • 各个模块运算表达式结构题的传递采用指针的方式,其余参数的传递都是数值传递,好比题目数量,最大数范围等

2.任务分配

  因为个人结对伙伴李同窗不擅长java,而我对Java情有独钟;因此通过商量,咱们决定用两种语言开发一个软件,分配任务以下:
(1)C、M层:李同窗采起c/c++编写,李同窗是驾驶员,我是领航员;数据结构

(2)V层:即视图层,采用java语言编写;我是驾驶员,李同窗是领航员;架构

(3)测试:因为前面李同窗编写了两层的大部分代码,我只编写了一层的代码。所以我来设计测试用例。

补充:编程期间必要时候角色能够互换一段时间,这样能够高效编程,作到人闲机不闲

3.编程环境

操做系统 window10
JDK 1.8.0_71
开发语言 java,C++
开发工具 eclipse Mars Release (4.5.0),Code Blocks
单元测试工具 Junit4.12,google test

3、结对编程

1.工做中的照片

2.软件运行结果展现


4.视图层核心代码展现

package site.yuanrui.four_arithmetic;

import java.awt.EventQueue;
import java.awt.FileDialog;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;

import site.yuanrui.Tools.*;

import javax.swing.JLabel;
import javax.swing.JOptionPane;

import java.awt.Font;
import java.awt.Frame;
import java.awt.Color;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.awt.event.ActionEvent;
import javax.swing.JTextArea;
/**
 * 主窗口类
 * @author YUANRUI
 *
 */
public class MainFrame extends JFrame {

    private JPanel contentPane;
    private JTextField textNum;
    private JTextField textCount;
    private JTextField textMax;

    /**
     * main函数入口
     * @param args参数列表
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    SubstanceTools.useSkin();//使用皮肤  
                    SubstanceTools.useTheme();//使用主题
                    MainFrame frame = new MainFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 窗口建立函数
     */
    public MainFrame() {
        setTitle("小学四则运算自动生成程序");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        setBounds(100, 100, 437, 339);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
        
        JLabel title = new JLabel("小学四则运算自动生成程序");
        title.setForeground(Color.BLACK);
        title.setFont(new Font("幼圆", Font.BOLD, 13));
        title.setBounds(128, 10, 171, 40);
        contentPane.add(title);
        
        JLabel lblNewLabel = new JLabel("题目数量:");
        lblNewLabel.setBounds(10, 63, 66, 15);
        contentPane.add(lblNewLabel);
        
        textNum = new JTextField();
        textNum.setBounds(70, 60, 66, 21);
        contentPane.add(textNum);
        textNum.setColumns(10);
        
        JLabel label = new JLabel("操做数个数:");
        label.setBounds(144, 63, 85, 15);
        contentPane.add(label);
        
        textCount = new JTextField();
        textCount.setBounds(215, 60, 66, 21);
        contentPane.add(textCount);
        textCount.setColumns(10);
        
        JLabel label_1 = new JLabel("最大数:");
        label_1.setBounds(291, 63, 54, 15);
        contentPane.add(label_1);
        
        textMax = new JTextField();
        textMax.setBounds(339, 60, 66, 21);
        contentPane.add(textMax);
        textMax.setColumns(10);
        
        JLabel label_2 = new JLabel("运算符选择:");
        label_2.setBounds(10, 100, 85, 15);
        contentPane.add(label_2);
        
        JButton OKbtn = new JButton("生成题目");
        
        OKbtn.setBounds(57, 171, 126, 37);
        contentPane.add(OKbtn);
        
        JCheckBox checkBoxAdd = new JCheckBox("+");
        checkBoxAdd.setBounds(84, 96, 47, 23);
        contentPane.add(checkBoxAdd);
        
        JCheckBox checkBoxSub = new JCheckBox("-");
        checkBoxSub.setBounds(128, 96, 38, 23);
        contentPane.add(checkBoxSub);
        
        JCheckBox checkBoxMul = new JCheckBox("*");
        checkBoxMul.setBounds(168, 96, 38, 23);
        contentPane.add(checkBoxMul);
        
        JCheckBox checkBoxDiv = new JCheckBox("/");
        checkBoxDiv.setBounds(210, 96, 47, 23);
        contentPane.add(checkBoxDiv);
        
        JLabel labelDel = new JLabel("小数:");
        labelDel.setBounds(10, 132, 45, 15);
        contentPane.add(labelDel);
        
        JCheckBox checkBoxDel = new JCheckBox("有");
        checkBoxDel.setBounds(48, 128, 47, 23);
        contentPane.add(checkBoxDel);
        
        JLabel label_3 = new JLabel("负数:");
        label_3.setBounds(168, 132, 47, 15);
        contentPane.add(label_3);
        
        JCheckBox checkBoxNeg = new JCheckBox("有");
        checkBoxNeg.setBounds(210, 128, 54, 23);
        contentPane.add(checkBoxNeg);
        
        JLabel label_4 = new JLabel("括号:");
        label_4.setBounds(301, 132, 44, 15);
        contentPane.add(label_4);
        
        JCheckBox checkBoxBra = new JCheckBox("有");
        checkBoxBra.setBounds(339, 128, 38, 23);
        contentPane.add(checkBoxBra);
        
        JTextArea textAreaResult = new JTextArea();
        textAreaResult.setBounds(10, 218, 411, 82);
        contentPane.add(textAreaResult);
        
        JButton buttonSave = new JButton("保存生成的题目");
    
        buttonSave.setBounds(251, 171, 126, 37);
        contentPane.add(buttonSave);
        
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(0, 187, 591, 98);
        contentPane.add(scrollPane);
        scrollPane.setViewportView(textAreaResult);
        /**
         * 生成题目点击事件
         */
        OKbtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int number = 0;
                int max = 10;
                int operandNumber = 2;
                int decimal = 0;
                int negative = 0;
                int bracketint = 0;
                int opreation = 0;
                if (checkBoxDel.isSelected()) {
                    decimal = 1;
                }
                if (checkBoxNeg.isSelected()) {
                    negative = 1;
                }
                if (checkBoxBra.isSelected()) {
                    bracketint = 1;
                }
                if (checkBoxDiv.isSelected()) {
                    opreation+=1;
                }
                if (checkBoxMul.isSelected()) {
                    opreation+=2;
                }
                if (checkBoxSub.isSelected()) {
                    opreation+=4;
                }
                if (checkBoxAdd.isSelected()) {
                    opreation+=8;
                }
                //参数验证
                try {
                    number = Integer.parseInt(textNum.getText());
                    max = Integer.parseInt(textMax.getText());
                    operandNumber = Integer.parseInt(textCount.getText());
                    
                } catch (Exception e2) {
                    e2.printStackTrace();
                    JOptionPane.showMessageDialog(null, "【题目数量、操做数、最大数格式错误,请从新输入】", "参数格式错误", JOptionPane.ERROR_MESSAGE);
                    System.out.println("【题目数量、操做数、最大数格式错误,请从新输入】");
                    return;
                }
                if (number>1000||number<=0) {
                    JOptionPane.showMessageDialog(null, "【题目数量范围1~1000,请从新输入】", "题目数量超出范围", JOptionPane.ERROR_MESSAGE);
                    System.out.println("【题目数量范围1~1000,请从新输入】");
                    return;
                    
                }
                if (max>1000||max<=2) {
                    JOptionPane.showMessageDialog(null, "【最大值范围1~1000,请从新输入】", "最大值超出范围", JOptionPane.ERROR_MESSAGE);
                    System.out.println("【最大值范围1~1000,请从新输入】");
                    return;
                    
                }
                if (operandNumber>20||operandNumber<=1) {
                    JOptionPane.showMessageDialog(null, "【操做数个数范围2~20,请从新输入】", "操做数个数超出范围", JOptionPane.ERROR_MESSAGE);
                    System.out.println("【操做数个数范围2~20,请从新输入】");
                    return;
                    
                }
                if (opreation>15||opreation<=0) {
                    JOptionPane.showMessageDialog(null, "【至少选择一个运算符】", "运算符选择错误", JOptionPane.ERROR_MESSAGE);
                    System.out.println("【至少选择一个运算符】");
                    return;
                    
                }
                
                String result = ShellTool.execCmd("Four_operation "+number+" "+max+" "+operandNumber+" "+decimal+" "+negative+" "+bracketint+" "+opreation+" 0",null);
                
                System.out.println(number+" "+max+" "+operandNumber+" "+decimal+" "+negative+" "+bracketint+" "+opreation+" 0");
                textAreaResult.setText(result);
            }
        }); 
        /**
         * 保存题目点击事件
         */
        buttonSave.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (textAreaResult.getText().isEmpty()) {
                    JOptionPane.showMessageDialog(null, "【请先点击生成题目】", "题目未生成", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                FileDialog openFile = new FileDialog(new Frame(), "另存为", FileDialog.SAVE);
                openFile.setVisible(true);
                
                String dirName=openFile.getDirectory();
                String fileName=openFile.getFile();
                
                if(dirName==null || fileName==null){
                    return;
                }
                try {
                    FileUtil.writeToFile(dirName+fileName+".txt",textAreaResult.getText());
                } catch (IOException e1) {
                    e1.printStackTrace();
                    System.out.println("文件写入错误!!!");
                }
            }
        });
        
    }
}

4、软件测试

一、设计测试用例

1)随机数生成模块测试用例
测试用例 参数 期待结果
测试用例1 0 0
测试用例2 5 0~4
2)运算符随机生成模块测试用例
测试用例 参数 期待结果
测试用例1 100,0 101
测试用例2 100,1 100,101
测试用例3 100,5 100,101
3)操做数生成模块测试用例
测试用例 参数 期待结果
测试用例1 10,0,0 10之内的正整数
测试用例2 10,1,0 10,0,0
测试用例3 10,0,1 10之内的整数
测试用例4 10,1,1 10之内的浮点数
4)去重模块测试用例
测试用例 参数 期待结果
测试用例1 {{12,8,10,4,20},{12,8,10,4,20}} true
4)求结果模块测试用
测试用例 参数 期待结果
测试用例1 {{12,8,10,4,20} 2
5)四则运算生成器测试用例
测试用例 参数 期待结果
测试用例1 10, 100, 4, 0, 0, 0, 15, 0 10道100之内的加减乘除正整数运算题

三、部分测试代码展现

四、测试结果展现

5、对方评价

1.对方性格评价

  李同窗是一个性格温和的人,善于思考,作事认真,力求完美的人。在结对编程过程当中,对于同一个问题有本身的见解,可以指出我编程过程当中出现的bug。当我遇到问题时,能提供一些思路,能把本身的想法和见解说出来;李同窗也是一个善问的人,在我当驾驶员的时候,当看不懂的时候,提出疑问,正是由于这样才使我经过讲解对本身的算法了解更深。同时李同窗仍是一个友善的人,善于合做和与交流,在和他的合做学习和探讨活动中,能选择本身擅长的方式(好比记笔记,画图)表述他的想法,互相交流本身的想法,能倾听和讨论咱们两我的之间不一样的意见。感触最深的是,李同窗在软件设计讨论中善于记笔记,这也是我从他身上学到的。记笔记方便后续的查看,也方便进一步讨论理清思路。跟李同窗进行合做能体会到合做的愉快和合做的高效率。大概就是这些。

2.对方编程习惯评价

  经过上一次结对编程之代码审查,我经过对他的代码进行了审查,并指出了一些不足,好比变量没有初始化;变量命名方式简单,不易读;函数之间的大空间参数传递没有用引用或者指针;重复的代码块未抽取等,在此次结对编程中李同窗对这几个方面有特别的注意,并进行的改正。李同窗的代码完整规范,有卓越的数据结构功底,这在他编写求值模块的过程当中能体会获得;敲代码速度快速,思惟广阔,想法独特有创新 。

6、总结

  经过结对编程实战,对结对编程的理解更透彻,而后就是经过结对编程实战使我从队友学习了一些本身身上所没有的东西。前面讨论如何分工,其实在真正编程的时候,分工跟预想的并不彻底同样,咱们首先讨论出了软件的具体架构,还有一些模块的核心算法。在编程中,有些算法由于不合适,改进了一些。那些算法改进的话程序效率提升的最多。其中算法的主要代码是咱们共同完成的,其中核心代码是李同窗完成的,李同窗主要是编写须要C语言编写的M、C层部分,我主要负责V层代码、测试和审查代码。

  零零散散历经大约一周时间完成,只有经历了才知道。就我的观点谈下结对编程的优缺点吧,首先说下好处。第一,能够发散思惟,两我的一个小时能讨论出来的东西,或许一我的一个星期都无法想出来,毕竟两我的看问题的角度不同。第2、边编程边复查,当一我的写出一段代码的时候,另外一我的做为旁观者每每更容易发现其中的问题,这就所谓“旁观者清,当局者迷”。第3、在技术和性格互补的状况下,能够极大提升开发效率,达到1+1>2的效果,好比李同窗用C语言编写后端代码,我用java编写前端视图代码。其次是缺点,最大的问题就是编程习惯问题,不一样的代码风格,在一块儿工做时会产生麻烦,尤为对于有强迫症的人;其次就是结对编程也容易滋生不良气氛,敷衍了事。而后两我的在一块儿工做可能会出现工做精力不能集中的状况。程序员可能会交谈一些与工做无关的事情,反而分散注意力,致使效率比单人更为低下;还有就是习惯了一我的敲代码,当有我的在旁边看着你敲,感受也挺别扭,进而影响进度。让我庆幸的是,在我和李同窗的结对编程中这些缺点不是很突出,多是性格和编程习惯各方面缘由。

  以上就是我对本次结对编程的感想,总的说来,经过结对编程的收获是很是大的,经过此次做业,不只学到了技术知识,并且更得到了许多宝贵的合做经验,更收获了深厚的友谊,期待下一次和李同窗的合做。

相关文章
相关标签/搜索