zoukankan      html  css  js  c++  java
  • JAVA课程实验报告 实验三 敏捷开发与XP实践

    北京电子科技学院(BESTI)

                  

    课程:Java程序设计  班级:1353  姓名:韩玉琪  学号:20135317

    成绩:             指导教师:娄嘉鹏             实验日期:2015.5.29

    实验密级:         预习程度:                     实验时间:15:30--18:00

    仪器组次:         必修/选修: 选修             实验序号:3

    实验名称:实验三 敏捷开发与XP实践                                             

    实验目的与要求:

    1. XP基础                               

    2. XP核心实践                           

    3. 相关工具                                     

    实验仪器:

    名称

    型号

    数量

    PC

    Lenovo

    1

    实验楼环境

    /

    1

    Eclipse

    /

    1

    一、实验内容及步骤

    (一)敏捷开发与XP

    1.了解什么是敏捷开发

    敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法。“敏捷流程”是一系列价值观和方法论的集合。

    2.认识XP(极限编程)

    极限编程是一种全新而快捷的软件开发方法。XP团队使用现场客户、特殊计划方法和持续测试来提供快速的反馈和全面的交流:

    (1)XP是以开发符合客户需要的软件为目标而产生的一种方法论

    (2)XP是一种以实践为基础的软件工程过程和思想

    (3)XP认为代码质量的重要程度超出人们一般所认为的程度

    (4)XP特别适合于小型的有责任心的、自觉自励的团队开发需求不确定或者迅速变化的软件

    3.XP软件开发的准则:沟通、简单、反馈、勇气

    XP软件开发的基石:编码、测试、倾听、设计

    4.我们关注的XP实践:编码标准,结对编程,代码集体所有,测试,重构等。通过学习这些实践,可以形成以测试为核心的开发流程:

     

    (二)编码标准

    1.编程标准是具有说明性的名字、清晰的表达式、直截了当的控制流、可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性。

    2.例:

     

    在Eclipse中解决:单击Eclipse菜单中的source->Format 或用快捷键Ctrl+Shift+F就可以按Eclipse规定的规范缩进,效果如下:

     

    3. Java中的一般的命名规则

    (1)要使命名有一定意义

    (2)包、类、变量用名词

    (3)方法名用动宾

    (4)包名全部小写,如:io,awt

    (5)类名第一个字母要大写,如:HelloWorldApp

    (6)变量名第一个字母要小写,如:userName

    (7)方法名第一个字母要小写:setName

    (三)结对编程

    1.结对编程的角色

    (1)驾驶员(Driver)是控制键盘输入的人。

    (2)领航员(Navigator)起到领航、提醒的作用。

    2.如何更好地实现结对编程

    (1)驾驶员:写设计文档,进行编码和单元测试等XP开发流程。

    (2)领航员:审阅驾驶员的文档、驾驶员对编码等开发流程的执行;考虑单元测试的覆盖率;思考是否需要和如何重构;帮助驾驶员解决具体的技术问题。

    (3)驾驶员和领航员不断轮换角色,不要连续工作超过一小时,每工作一小时休息15分钟。领航员要控制时间。

    (4)主动参与。任何一个任务都首先是两个人的责任,也是所有人的责任。

    (5)只有水平上的差距,没有级别上的差异。

    3.团队合作:同理心、互利、对事情不对人。

    (四)版本控制

    1.优点

    (1)版本控制提供项目级的 undo(撤销)功能 没有什么事情是终结版本,任何错误必须很容易回滚。

    (2)版本控制允许多人在同一代码上工作,只要遵守一定的控制原则就行。

    (3)版本控制系统保存了过去所作的修改的历史记录。

    (4)版本控制系统支持在主线上开发的同时发布多个软件版本。

    (5)版本控制也是项目级的时间机器,你可以选择任何一个时间, 精确地查看项目在当时的情况。

    2.开通我的代码库:http://git.shiyanlou.com/hyq20135317

    3.学习如何将代码提交到代码库

    $ cd /home/shiyanlou/Code/shiyanlou_cs212

    # 修改代码文件

    # 添加修改文件

    $ git add 所有修改的文件

    # 提交到环境中本地代码仓库

    $ git commit -m '本次修改的描述'

    # push到git.shiyanlou.com,无需输入密码

    $ git push

    4.实际操作:

    进入目录→创建vi文本→编译成功→运行成功(见下图)→将代码push到代码库中(我的失误,这个截图丢了….但是后面有push自己编写的小游戏的代码)

     

    Git log HelloWorld查看记录:

     

    (五)重构

    1. 概念

    重构(Refactor),就是在不改变软件外部行为的基础上,改变软件内部的结构,使其更加易于阅读、易于维护和易于变更。

    2. eclipse中Refactor

    重新命名:Rename

    封装成员变量:Encapsulate Field...

    抽象方法:Extract Method...

     

     

    3.实用的方法

     

    4. 完整的重构流程包括:

    从版本控制系统代码库中Check out code→读懂代码(包括测试代码)→发现bad smell→Refactoring→运行所有的Unit Tests→往代码库中Check in code

    (六)实践项目

    1.团队成员

    结对伙伴:20135337 朱荟潼

    博客:http://www.cnblogs.com/zzzz5

    主要负责:伪代码编写、测试代码编写

    20135317韩玉琪

    Git:http://git.shiyanlou.com/hyq20135317

    主要负责:产品代码编写、用户测试并程序修改完善代码

    2.伪代码、测试代码(见http://www.cnblogs.com/zzzz5)

    3.产品代码

    包含三个大部分:

    (1)入口:

    package game;

    public class AnswerQuestion {

        public static void main(String args[]) {

            new Function();

        }

    }

    (2)设置GUI界面及其功能:

    public class Function implements ActionListener{

            public Function(){

            //初始化面板,调用响应功能

            }

            public void readFile() {

            //以特殊字符为标识,读取文件中相应内容

            }

            public void ifRight() {

            //判断答题者选择的对错

            }

            public void setQuestion(int index) {

            //将下标为index的题目内容显示出来

            }

            public void actionPerformed(ActionEvent e) {

            //监听用户操作,并执行对应操作

            }

    }

    详细设计:

    package game;

     

    import javax.swing.*;

     

    import java.awt.*;

    import java.io.*;

    import java.awt.event.*;

     

    public class Function implements ActionListener {

        private static final String SRC_GAMEFILE_题目_TXT = "src/gamefile/题目.txt";

        private static final int Q_Number = 100;

        JFrame f = new JFrame("答题练习小游戏");

        JPanel p1 = new JPanel();

        JPanel p2 = new JPanel();

        JPanel p3 = new JPanel();

        JPanel p4 = new JPanel();

     

        int index = 0, total = 0;

        QuestionBank questions[] = new QuestionBank[Q_Number];

     

        JLabel questionString = new JLabel("题目:");

        JLabel choiceString = new JLabel("选项:");

        JLabel totalString = new JLabel("你的得分:");

        TextArea question = new TextArea(" 游戏规则: 1.点击“开始”进行答题,点击下一题继续 2.答题过程中点击“重新练习”,从第一道题作答,分数归0 3.答题过程中点击“开始”从第一道题作答,分数累计. 现在,请单击<开始>进行游戏", 5, 60, 3);

        JTextField totaltf = new JTextField("0", 5);

     

        JRadioButton choiceA = new JRadioButton("a");

        JRadioButton choiceB = new JRadioButton("b");

        JRadioButton choiceC = new JRadioButton("c");

        JRadioButton choiceD = new JRadioButton("d");

     

        ButtonGroup Group = new ButtonGroup();

     

        JButton beginbt = new JButton("开始");

        JButton nextbt = new JButton("下一个题目");

        JButton practiceAgainbt = new JButton("重新练习");

     

        File file = new File(SRC_GAMEFILE_题目_TXT);

     

        public Function() {

            f.setSize(750, 600);

            f.setLocation(250, 50);

            f.setVisible(true);

     

            f.setLayout(new GridLayout(4, 1, 15, 15));

            p1.setLayout(new FlowLayout(FlowLayout.CENTER));

            p2.setLayout(new FlowLayout(FlowLayout.CENTER));

            p3.setLayout(new FlowLayout(FlowLayout.CENTER));

            p4.setLayout(new FlowLayout(FlowLayout.CENTER));

     

            Group.add(choiceA);

            Group.add(choiceB);

            Group.add(choiceC);

            Group.add(choiceD);

     

            p1.add(questionString);

            p1.add(question);

     

            p2.add(choiceString);

            p2.add(choiceA);

            p2.add(choiceB);

            p2.add(choiceC);

            p2.add(choiceD);

     

            p3.add(totalString);

            p3.add(totaltf);

     

            p4.add(beginbt);

            p4.add(nextbt);

            p4.add(practiceAgainbt);

     

            f.add(p1);

            f.add(p2);

            f.add(p3);

            f.add(p4);

     

            nextbt.addActionListener(this);

            beginbt.addActionListener(this);

            practiceAgainbt.addActionListener(this);

     

            readFile();

        }

     

        public void readFile() {

            String s, question, choiceA, choiceB, choiceC, choiceD, answer;

            try {

                int count = 0;

                FileInputStream in = new FileInputStream(file);

                byte b[] = new byte[in.available()];

                in.read(b);

                s = new String(b);

                String c[] = s.split("&&");

                for (int i = 0; i < c.length; i++) {

                    question = c[i++];

                    choiceA = c[i++];

                    choiceB = c[i++];

                    choiceC = c[i++];

                    choiceD = c[i++];

                    answer = c[i];

                    questions[count++] = new QuestionBank(question, choiceA,choiceB, choiceC, choiceD, answer);

                }

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

     

        public void ifRight() {

            if (choiceA.isSelected()) {

                if (questions[index].answer.equals(choiceA.getText())) {

                    total++;

                }

            }

            if (choiceB.isSelected()) {

                if (questions[index].answer.equals(choiceB.getText())) {

                    total++;

                }

            }

            if (choiceC.isSelected()) {

                if (questions[index].answer.equals(choiceC.getText())) {

                    total++;

                }

            }

            if (choiceD.isSelected()) {

                if (questions[index].answer.equals(choiceD.getText())) {

                    total++;

                }

            }

            totaltf.setText(Integer.toString(total));

        }

     

        public void setQuestion(int index) {

            question.setText(questions[index].question);

            choiceA.setText(questions[index].choiceA);

            choiceB.setText(questions[index].choiceB);

            choiceC.setText(questions[index].choiceC);

            choiceD.setText(questions[index].choiceD);

            Group.clearSelection();

        }

     

            public void actionPerformed(ActionEvent e) {

           

            if (e.getSource() == nextbt) {

                ifRight();

                if (index < questions.length) {

                    setQuestion(++index);

                }

            }

            if (e.getSource() == practiceAgainbt) {

                totaltf.setText(Integer.toString(0));

                index = 0;

                total = 0;

                tryAgain();

            }

            if (e.getSource() == beginbt) {

                index=0;

                if (total != 0) {

                    tryAgain();

                }else{

                    setQuestion(0);

                }

            }

        }

     

        private void tryAgain() {

            ifRight();

            if (index < questions.length) {

                setQuestion(index);

            }

        }}

    (3)存放文件中读取出的题目:

                package game;

                public class QuestionBank {

                    String question;

                    String choiceA, choiceB, choiceC, choiceD;

                    String answer;

                    QuestionBank(String question, String choiceA, String choiceB,String choiceC, String choiceD, String answer) {

                        this.question = question;

                        this.choiceA = choiceA;

                        this.choiceB = choiceB;

                        this.choiceC = choiceC;

                        this.choiceD = choiceD;

                        this.answer = answer;

                    }

                }

    4.遇到的问题与改进

    (1)最开始写好了之后,在界面上测试,发现点击“重新练习”之后题目马上变成了第一道,但是分数还是原来的分数,而且在第一道题打完之后,不论答得对错,得分都会变成零分。

    当时写的代码是这样的:

    public void actionPerformed(ActionEvent e)

             {

                      if(e.getSource() == nextbt)

                      {

                                ifRight();

                                if(index<questions.length)

                                {

                                         setQuestion(++index);

                                }

                               

                      }

                      if(e.getSource() == beginbt)

                      {

                                setQuestion(0);

                      }

                      if(e.getSource() == practiceAgainbt)

                      {

                                setQuestion(0);

                                total = 0;

                      }

             }

    我认为在ifRight中已经有totaltf.setText(Integer.toString(total));就不需要再这里加了,但是显然不行。于是就将total=0前面加了一句:

    totaltf.setText(Integer.toString(0));

    但是问题又来了,虽然点击“重新开始”之后得分已经变成了0,但是第一道题不论对错,依然是0分。

    这个问题困扰了我很久。在多次尝试修改无果之后。我自己开始反思这个思路是不是正确,然后发现,可能我在调用ifRight的时候就是这个监控的另一次了?所以我打算增加代码判断,就改成了:

    public void actionPerformed(ActionEvent e) {

           

            if (e.getSource() == nextbt) {

                ifRight();

                if (index < questions.length) {

                    setQuestion(++index);

                }

            }

            if (e.getSource() == practiceAgainbt) {

                totaltf.setText(Integer.toString(0));

                index = 0;

                total = 0;

                ifRight();

                if (index < questions.length) {

                    setQuestion(index);

                }

            }

            if (e.getSource() == beginbt) {

                index=0;

                if (total != 0) {

                    ifRight();

                    if (index < questions.length) {

                        setQuestion(index);

                    }

                }else{

                    setQuestion(0);

                }

            }

        }

    将其中ifRight();

    if (index < questions.length) {setQuestion(index);}部分

    方法用重构抽取,命名为tryAgain

    (2)文件相对路径无法打开

    开始的时候文件我用的是绝对路径,但是后来再放进src中的时候,文件一直无法打开。然后我尝试了很多次,发现可能是eclipse自身的问题读不出来,然后就在eclipse里面建立一个txt文件,成功打开。

    (3)重构:(掌握的不够好)

    重新命名

    抽取常量

    private static final String SRC_GAMEFILE_题目_TXT = "src/gamefile/题目.txt";

    private static final int Q_Number = 100;

    抽取方法

    private void tryAgain() {

            ifRight();

            if (index < questions.length) {

                setQuestion(index);

            }

        }

    5.运行

     

    6.将代码push到代码库(因为实验楼不认中文,所以做了一些改动)

     

     

     

    二、实验总结

    步骤

    耗时

    百分比

    需求分析

    25min

    4%

    设计

    30min

    5%

    代码实现

    360min

    57%

    测试

    150min

    23%

    分析总结

    65min

    10%

      1.每次java实验都是一个大工程,这次尤其难。因为之前学的不扎实,应用能力弱,所以花的时间特别多,每天一下课就开始弄,晚上还熬夜;做出来的东西还特别low;遇到问题特别烦,就是上面的那个得分的问题,一直整了两天才改成符合最初设计构想的代码。

      2.我觉得实验楼是一个很好的平台,老师每次的实验内容都很丰富,但是总感觉有点吃不消。就像这次的重构,虽然能跟着做,简单的也会,但是真正在自己的程序里用起来好难啊。还是没有修炼到家,需要提高自己的能力。

      3.结对编程的方式、版本控制的方法都掌握的不够熟练,还需要继续学习。

      4.这次我觉得我意外的一个收获是把VIM编辑器的基本操作学会了

          按一下i键,下端显示 --INSERT--插入命令

          Esc:退出i(插入)命令进行其它命令使用(实在不行Ctrl+C也好使)
                     wq:保存文件并退出
                     ZZ:保存文件并退出,同上一个命令,注意大写

                     q!:强制退出,不保存

                   u :撤消上一步操作

  • 相关阅读:
    [luogu2059 JLOI2013] 卡牌游戏 (概率dp)
    [luogu1772 ZJOI2006] 物流运输 (最短路 线性dp)
    [luogu 2568] GCD (欧拉函数)
    [poj 2976] Dropping tests (分数规划 二分)
    cf掉分记——Avito Code Challenge 2018
    新博客的第一篇博文~
    [noip2011 luogu1312] Mayan游戏(模拟)
    bzoj2618 [Cqoi2006]凸多边形
    LLppdd never give up!
    我的scoi2018
  • 原文地址:https://www.cnblogs.com/hyq20135317/p/4553557.html
Copyright © 2011-2022 走看看