实验三 敏捷开发与XP实践

20155224 实验三 敏捷开发与XP实践 实验报告


实验报告封面:

课程:Java程序设计  班级:1652班  姓名:王高源 学号:20165225

指导教师:娄嘉鹏 实验日期:2018年4月27日

实验时间:3:35 - 5:15 实验序号:实验三

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

实验内容:
1.XP基础
2.XP核心实践
3.相关工具

实验要求:

- 没有Linux基础的同学建议先学习《Linux基础入门(新版)》《Vim编辑器》 课程

- 完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。报告可以参考范飞龙老师的指导

- 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。

实验步骤:

(一)编码标准
  • 编程标准使代码更容易阅读和理解,甚至可以保证其中的错误更少。编程标准包含:具有说明性的名字、清晰的表达式、直截了当的控制流、可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性。

  • 关于程序的缩进,在IDEA中比较智能,它会帮你自动进行缩进,这样也使得程序的可读性大大增强。

  • Java中的一般命名规则:

1.要体现各自的含义

2.包、类、变量用名词

3.方法名用动宾

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

5.第一个字母要大写,如:HelloWorldApp

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

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

8.在团队操作中,格式规范是为提高效率扫清障碍的做法;命名规

9.范则具有很强灵活性,根据各团队不同的情况和习惯进行,不仅是方便自己,更是方便团队其他成员。

  • 结对编程:

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

  • 我们常见的代码如下:

public class CodeStandard {
public static void main(String [] args){
StringBuffer buffer = new StringBuffer();
buffer.append('S');
buffer.append("tringBuffer");
System.out.println(buffer.charAt(1));
System.out.println(buffer.capacity());
System.out.println(buffer.indexOf("tring"));
System.out.println("buffer = " + buffer.toString());
if(buffer.capacity()<20)
buffer.append("1234567");
for(int i=0; i<buffer.length();i++)
System.out.println(buffer.charAt(i));
}
}
  • 但是这样的代码没有缩进,读的很费力,所以我们应该在idea中使用Code->Reformate Code去格式化代码。

  • 代码重新格式化后效果如下:

public class CodeStandard {
        public static void main(String [] args){
            StringBuffer buffer = new       StringBuffer();
            buffer.append('S');
            buffer.append("tringBuffer");
            System.out.println(buffer.charAt(1));
            System.out.println(buffer.capacity());
            System.out.println(buffer.indexOf("tring"));
            System.out.println("buffer = " + buffer.toString());
            if(buffer.capacity()<20)
                buffer.append("1234567");
            for(int i=0; i<buffer.length();i++)
                System.out.println(buffer.charAt(i));
        }
    }

image

  • 其实idea还有很多十分实用的功能,如:Surround With(Ctrl+Alt+T):可使用if-else、try-catch、do-while等包装代码段,极大地简化了我们的编程时间:

image

(二)敏捷开发与XP

  • 在码云上把自己的学习搭档加入自己的项目中,确认搭档的项目加入自己后,下载搭档实验二的Complex代码,加入不少于三个JUnit单元测试用例,测试成功后git add .; git commit -m "自己学号 添加内容";git push;

  • 完成重构内容的练习,下载搭档的代码,至少进行三项重构,提交重构后代码的截图,加上自己的学号水印。提交搭档的码云项目链接。

  • 以结对的方式完成Java密码学相关内容的学习,结合重构,git,代码标准。提交学习成果码云链接和代表性成果截图,要有学号水印。

  • 搭档代码:

import java.lang.Integer;
import java.util.Objects;

public class Complex {
    //定义属性并生成getter,setter
    double RealPart;
    double ImagePart;
    public double getRealPart(){
        return RealPart;
    }
    public double getImagePart(){
        return ImagePart;
    }

    //定义构造函数
    public Complex(){
        RealPart = 0;
        ImagePart = 1;
    }
    public Complex(double R,double I){
        RealPart = R;
        ImagePart = I;
    }

    //Override Object
    public boolean equals(Object obj){
        if(this == obj){
            return true;
        }
        if(!(obj instanceof Complex)) {
            return false;
        }
        Complex complex = (Complex) obj;
        if(complex.RealPart != ((Complex) obj).RealPart) {
            return false;
        }
        if(complex.ImagePart != ((Complex) obj).ImagePart) {
            return false;
        }
        return true;
    }
    public String toString(){
        String s = new String();
        if (ImagePart > 0){
            s = getRealPart() + "+" + getImagePart() + "i";
        }
        if (ImagePart == 0){
            s = getRealPart() + "";
        }
        if(ImagePart < 0){
            s = getRealPart() + "" + getImagePart() + "i";
        }
        if(RealPart == 0){
            s = getImagePart() + "i";
        }
        return s;
    }
    //定义公有方法:加减乘除
    Complex ComplexAdd(Complex a){
        return new Complex(RealPart + a.RealPart,ImagePart + a.ImagePart);
    }
    Complex ComplexSub(Complex a){
        return new Complex(RealPart - a.RealPart,ImagePart - a.ImagePart);
    }
    Complex ComplexMulti(Complex a){
        return new Complex(RealPart*a.RealPart-ImagePart*a.ImagePart,RealPart*a.ImagePart + ImagePart*a.RealPart);
    }
    Complex ComplexDiv(Complex a) {
        return new Complex((RealPart * a.ImagePart + ImagePart * a.RealPart) / (a.ImagePart * a.ImagePart + a.RealPart * a.RealPart), (ImagePart * a.ImagePart + RealPart * a.RealPart) / (a.RealPart * a.RealPart + a.RealPart * a.RealPart));
    }
}
  • 测试代码:
import static org.junit.Assert.*;
import org.junit.Test;
import junit.framework.TestCase;
public class ComplexTest extends TestCase {
    Complex complex = new Complex(1,1);
    @Test
    public void testAdd(){
        assertEquals(new Complex(3.3,3.4), complex.ComplexAdd(new Complex(2.3,2.4)));
    }
    //测试加法
    @Test
    public void testSub(){
        assertEquals(new Complex(-5.3,-2.4), complex.ComplexSub(new Complex(6.3,3.4)));
    }
    //测试减法
    @Test
    public void testMulti(){
        assertEquals(new Complex(3.0,2.0), complex.ComplexMulti(new Complex(3.0,2.0)));
    }
    //测试乘法
    @Test
    public void testDiv(){
        assertEquals(new Complex(1.0,1.0), complex.ComplexDiv(new Complex(1.0,1.0)));
        assertEquals(new Complex(0.0,0.0), complex.ComplexDiv(new Complex(1.0,0.0)));
        //assertEquals(new Complex(0.0,0.0), complex.ComplexDiv(new Complex(3,4)));
        //边缘测试
    }
    @Test
    public void testequals(){
        assertEquals(true, complex.equals(new Complex(1.0,1.0)));
    }
    //测试判断相等
}
  • 测试结果如下:

image

  • 搭档加入码云项目:

image

  • git命令上传代码:
$ cd /home/shiyanlou/Code/shiyanlou_cs212
# 修改代码文件
# 添加修改文件
$ git add 所有修改的文件
# 提交到环境中本地代码仓库
$ git commit -m '本次修改的描述'
# push到git.shiyanlou.com,无需输入密码
$ git push
  • 码云上传截图:

image

(三)重构

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

  • 我们仍以搭档的complex为例:

-如图选择重构项目:

image

重构结果如下:

image

(四)练习

  • 维吉尼亚密码:
import java.sql.SQLOutput;

public class vigenere
{

    //输入明文和密钥,用输入的密钥对明文进行加密
    public static void main(String[] args) {
        int i,j,sum,o;
        double q,w;
        int e=0;
        double rate;
        char[] c = new char[300];
        char[] k1 = new char[300];
        char[] k2=new  char[100];
        char word='a';
        for (i=0;i<26;i++) {
            k2[i]=word;
            word++;
        }


//输入
        System.out.print("enter a mingwen string:");
        String m = MyInput.readString();
        System.out.print("enter a key string:");
        String k = MyInput.readString();

//构造密钥对照表

        for (i = 0; i < k.length(); i++) {
            if (k.charAt(i) >= 'a' && k.charAt(i) <= 'z')
                k1[i] = (char) (k.charAt(i) - 97);
            if (k.charAt(i) >= 'A' && k.charAt(i) <= 'Z')
                k1[i] = (char) (k.charAt(i) - 65);
        }

//加密

        for (i = 0; i < m.length(); i++) {
            if (m.charAt(i) >= 'a' && m.charAt(i) <= 'z')
                c[i] = (char) ((m.charAt(i) - 97 + k1[i % k.length()]) % 26 + 97);
            if (m.charAt(i) >= 'A' && m.charAt(i) <= 'Z')
                c[i] = (char) ((m.charAt(i) - 65 + k1[i % k.length()]) % 26 + 65);
        }
//计算密文长度
        o=i;
        System.out.println("密文单词个数为"+o);
        System.out.print("密文为");
//输出密文
        for (i = 0; i < c.length; i++) {
            System.out.print(c[i]);
        }
        System.out.println();
        System.out.println("以下是各字母出现的频率");

//计算每个字母出现的次数和频率
        for(j=0;j<=25;j++){
            for(i=0;i<o;i++){
                if(c[i]==k2[j]){
                    e++;
                }
            }
            System.out.printf(k2[j]+"出现次数为"+e);
            q=e;
            w=o;
            rate=(q/w)*100;
            System.out.println("频率为"+rate+"%");
            e=0;
        }
//计算重合指数
        for(i=0;i<o;i++){
            for(j=1;j<o;j++){
                if(c[i]==c[j]){
                    e++;
                }
            }
        }
        q=e;
        sum=0;
        for(i=o;i>0;i--){
            sum=i+sum;
        }
        w=sum;
        rate=(q/w)*100;
        System.out.println("重合指数为"+rate+"%");
    }
}
import java.io.*;

public class MyInput {
    public static String readString() {
        BufferedReader br
                = new BufferedReader(new InputStreamReader(System.in), 1);
        String string = "";
        try {
            string = br.readLine();
        } catch (IOException ex) {
            System.out.println(ex);
        }
        return string;
    }
}
  • 截图:
    image

  • 运行结果已放在蓝墨云中。

(五)实验过程中遇到的问题及解决

  • clone连接超时:

image

  • 结果发现是自己粘贴的有点过了....

  • 已解决:

image

(六)PSP(Personal Software Process)时间

步骤 耗时 百分比
需求分析 20min 12.5%
设计 25min 15.6%
代码实现 60min 37.5%
测试 35min 21.9%
分析总结 20min 12.5%

心得体会:

  • 首先,结对学习真的很棒,还很省心。

  • 其次,通过这次实验,我们都简单了解了Java实现密码学算法的方式,由于Java庞大的通用API积累,使用起来确实比C语言这种面向过程的语言方便了不少。

  • 最后,附:20165213-周启航博客链接

posted @ 2018-04-28 15:32  牛奶仔丶  Views(183)  Comments(1Edit  收藏  举报