20145215实验三 敏捷开发与XP实践

实验内容

  1. XP基础
  2. XP核心实践
  3. 相关工具

实验步骤

(一)敏捷开发与XP

  • 软件工程是把系统的、有序的、可量化的方法应用到软件的开发、运营和维护上的过程。软件工程包括下列领域:软件需求分析、软件设计、软件构建、软件测试和软件维护。
  • 敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法。敏捷开发包括很多模式:
  • 一项实践在XP环境中成功使用的依据通过XP的法则呈现,包括:快速反馈、假设简单性、递增更改、提倡更改、优质工作。XP软件开发的基石是XP的活动,包括:编码、测试、倾听、设计。
  • XP是一种更加灵活的开发方式和理念,通过迅速的反应及时充分修改程序,保证所有团队成员对资源和责任的共享;适用于“小而精”的团队开发。同时,其所倡导的“倾听”也是实现了程序开发“需求至上”的终极目标。

(二)编码标准

  • 编程标准使代码更容易阅读和理解,甚至可以保证其中的错误更少。编程标准包含:具有说明性的名字、清晰的表达式、直截了当的控制流、可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性。
  • 关于程序的缩进,在IDEA中比较智能,它会帮你自动进行缩进,这样也使得程序的可读性大大增强。
  • Java中的一般命名规则:
  1. 要体现各自的含义
  2. 包、类、变量用名词
  3. 方法名用动宾
  4. 包名全部小写,如:io,awt
  5. 类名第一个字母要大写,如:HelloWorldApp
  6. 变量名第一个字母要小写,如:userName
  7. 方法名第一个字母要小写:setName
  • 在团队操作中,格式规范是为提高效率扫清障碍的做法;命名规范则具有很强灵活性,根据各团队不同的情况和习惯进行,不仅是方便自己,更是方便团队其他成员。

(三)结对编程

  • 结对编程中的两个重要角色:驾驶员(Driver)是控制键盘输入的人,领航员(Navigator)起到领航、提醒的作用。
  • 驾驶员:写设计文档,进行编码和单元测试等XP开发流程。领航员:审阅驾驶员的文档、驾驶员对编码等开发流程的执行;考虑单元测试的覆盖率;思考是否需要和如何重构;帮助驾驶员解决具体的技术问题。
  • 驾驶员和领航员不断轮换角色,不要连续工作超过一小时,每工作一小时休息15分钟。领航员要控制时间。

(四)版本控制

  • 版本控制提供项目级的 undo(撤销) 功能;
  • 版本控制允许多人在同一代码上工作;
  • 版本控制系统保存了过去所作的修改的历史记录;
  • git命令上传代码:
$ cd /home/shiyanlou/Code/shiyanlou_cs212
# 修改代码文件
# 添加修改文件
$ git add 所有修改的文件
# 提交到环境中本地代码仓库
$ git commit -m '本次修改的描述'
# push到git.shiyanlou.com,无需输入密码
$ git push
  • 在此分享一下git上传的过程:
  1. 首先打开需要上传的项目文件夹,鼠标右键点击Git Bash Here,接着输入指令git init.
  2. devops 敏捷开发 敏捷开发xp_devops 敏捷开发

  3. 输入指令git add .
  4. devops 敏捷开发 敏捷开发xp_devops 敏捷开发_02

  5. 输入指令git commit -m "你想写的注释"(也可以用git commit -a,它会自动检查应该commit什么文件。如果是新增的文件,仍然要使用git add来添加)
  6. devops 敏捷开发 敏捷开发xp_git_03

  7. 接着git remote add origin http://项目地址,再git push origin master,按要求输入用户名及密码就OK了,如果有什么问题请参考关于开源中国的代码托管
  8. devops 敏捷开发 敏捷开发xp_git_04

(五)重构

  • 重构(Refactor),就是在不改变软件外部行为的基础上,改变软件内部的结构,使其更加易于阅读、易于维护和易于变更 。重构最主要的目标就是清楚“有臭味道”的代码,主要表现为重复代码。
  • 在此介绍一下IDEA中如何进行重构:

devops 敏捷开发 敏捷开发xp_团队开发_05

  1. 鼠标放在name上,右键->Refactor->Encapsulate Field...
  2. devops 敏捷开发 敏捷开发xp_git_06

  3. 如图所示,选择Refactor
  4. devops 敏捷开发 敏捷开发xp_团队开发_07

  5. 重构完的效果如下图所示:
  6. devops 敏捷开发 敏捷开发xp_git_08

  7. 同样,我们也可以对age、id进行重构,效果如下:
  8. devops 敏捷开发 敏捷开发xp_git_09

  • 此外,我们还可以在IDEA中给Student类产生一个toString方法:
  1. 鼠标点击Code->Generate...
  2. devops 敏捷开发 敏捷开发xp_devops 敏捷开发_10

  3. 选择toString
  4. devops 敏捷开发 敏捷开发xp_团队开发_11

  5. 点OK
  6. devops 敏捷开发 敏捷开发xp_上传_12

  7. 效果如图所示:
  8. devops 敏捷开发 敏捷开发xp_团队开发_13

(六)实践项目

我们团队由两名成员组成,各有分工:

20145215卢肖明:负责前期学习的整理工作,将java代码进行必要注释,并对TDD内容进行补充;进行后期测试;
20145221高其:负责中期的测试代码开发;进行后期测试

  • 先在开源中国上添加项目成员:

devops 敏捷开发 敏捷开发xp_团队开发_14

  • 我们打算利用在上次实验中所设计的Complex代码进行TDD(Test Driven Development, 测试驱动开发):
  1. 首先,先由我将产品的伪代码托管到我的开源中国账户上:
  2. devops 敏捷开发 敏捷开发xp_devops 敏捷开发_15

  3. 高其再在他的电脑上输入git clone 我的项目地址,将我所上传的伪代码下载下来:
  4. devops 敏捷开发 敏捷开发xp_团队开发_16

再根据我的伪代码,编写出了测试代码,并上传到我的账户:

devops 敏捷开发 敏捷开发xp_devops 敏捷开发_17

devops 敏捷开发 敏捷开发xp_上传_18

devops 敏捷开发 敏捷开发xp_git_19

  1. 我再从网站上将代码克隆下来,进行产品代码的初步编写:

编写完成之后再次上传,高其再对它进行修改以及重构,最终完成了Complex代码的编写:

package exp03;
public class MyComplex {
    private static int r;
    private static int i;
    private double m;
    private double n;
    public static int getRealPart(int RealPart){
        setR(RealPart);
        return getR();
    }
    public static int getImaginePart(int ImaginePart){
        setI(ImaginePart);
        return getI();
    }
    public MyComplex(double m, double n) {
        this.setM(m);
        this.setN(n);
    }

    public static int getR() {
        return r;
    }

    public static void setR(int r) {
        MyComplex.r = r;
    }

    public static int getI() {
        return i;
    }

    public static void setI(int i) {
        MyComplex.i = i;
    }

    public MyComplex add(MyComplex c) {
        return new MyComplex(getM() + c.getM(), getN() + c.getN());
    }
    public MyComplex minus(MyComplex c) {
        return new MyComplex(getM() - c.getM(), getN() - c.getN());
    }
    public MyComplex multiply(MyComplex c) {
        return new MyComplex(getM() * c.getM() - getN() * c.getN(), getM() * c.getN() + getN() * c.getM());
    }
    public String toString() {
        String rtr_str = "";
        if (getN() > 0)
            rtr_str = "(" + getM() + "+" + getN() + "i" + ")";
        if (getN() == 0)
            rtr_str = "(" + getM() + ")";
        if (getN() < 0)
            rtr_str = "(" + getM() + getN() + "i" + ")";
        return rtr_str;
    }

    public double getM() {
        return m;
    }

    public void setM(double m) {
        this.m = m;
    }

    public double getN() {
        return n;
    }

    public void setN(double n) {
        this.n = n;
    }
}

devops 敏捷开发 敏捷开发xp_git_20

PSP(Personal Software Process)时间

步骤

耗时

百分比

需求分析

20min

12.5%

设计

25min

15.6%

代码实现

60min

37.5%

测试

35min

21.9%

分析总结

20min

12.5%

总结

本次实验最关键的地方在于团队合作,通过团队合作,我们不仅对团队开发这一概念有了深刻认识,更对XP这一思想有了初步的理解。我觉得之所以要在这个过程中提倡团队开发,首先,软件开发的过程复杂,而团队方式可以使其简单许多,遇到问题的时候可以大家一起想,集思广益,特别是在一个较大型的软件工程项目中,一个人的力量和智慧显然是不够的。其次,团队操作在很大程度上可以实现优势的互补。例如在做软件的时候,一方面需要实现强大的功能,另一方面需要有良好美观的界面,这两个方面就需要两个分别擅长其中一项的人来进行合作。对于我们目前比较简单的代码来说,团队开发可能并不能很好的体现其优势,但是在我们以后做大项目的时候,团队开发将会给我们提供很多方便,也增加了开发人员之间的交流,何乐而不为呢?