其他分享
首页 > 其他分享> > 20175308 实验三《敏捷开发与XP实践》

20175308 实验三《敏捷开发与XP实践》

作者:互联网

20175308 实验三《敏捷开发与XP实践》

实验要求

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

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

    实验步骤

    敏捷开发与XP(概念)

敏捷开发(Agile Development):

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

XP(eXtreme Programming):

极限编程,是一种全新而快捷的软件开发方法。
XP准则:

XP的活动:编码、测试、倾听、设计
XP实践:项目成员用户成功执行XP活动的技术通过XP实践来呈现,包括编程、团队、过程相关的12条实践
我们关注其中的编码标准结对编程代码集体所有测试重构

(一)、编码标准

程序大多时候是给人看的,编程标准使代码更容易阅读和理解,甚至可以保证其中的错误更少。它包含:

alibaba将问题分为blockcriticalmajor三个级别,从扫描结果中我们看出,虽然代码运行正确,但是有着诸多不规范之处。我们之前往往追求代码的正确运行,而代码的规范与否却是我们没有注意过的。

对代码进行规范处理

代码标准中很重要的一项是如何给包、类、变量、方法等标识符命名。Java中的一般的命名规则有:

其次,根据我们扫描结果的反馈信息,我们的代码中还存在着以下不规范之处:

对上述不规范的地方进行相应的修改,规范后的代码如下:

/**
 * CodeStandard class
 *
 * @author Fomalhaut5308
 * @date 2019/4/29
 */
public class CodeStandard {
    public static void main(String[] args) {
        int a = 20;
        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() < a) {
            buffer.append("1234567");
        }
        for (int i = 0; i < buffer.length(); i++) {
            System.out.println(buffer.charAt(i));
        }
    }
}

Code菜单

本次实验中要求在IDEA中使用Code->Reformate Code将代码格式化。除了格式化功能外,Code菜单还具备以下功能:

几个重点的功能:

其他的功能个人觉得比较鸡肋。(具体功能可参考本链接)但一项功能的设定必有其存在的需求,在不需要这些功能的情景下你可能并不会感觉这些功能的必要,但是当你存在相应需求时,或许你会感谢这些快速高效的功能。

(二)、结对编程-版本控制

添加搭档

在码云中点击管理->添加仓库成员->邀请用户,发送邀请链接后等待对方接受即可将搭档添加进码云仓库,双方互相进行如此操作。(下图仅供参考,这个是已经将搭档拉入项目后的截图)

下载Complex代码并加入代码测试

测试代码运行如下(实验二已有,这里不做赘述):

对搭档的代码添加至少三处重构

搭档原代码

public class myComplex {
        // 定义属性并生成getter,setter
        double RealPart;
        double ImagePart;
        // 定义构造函数
        myComplex(double R,double I){
            RealPart=R;
            ImagePart=I;
        }
        // 定义公有方法:加减乘除
        myComplex ComplexAdd(myComplex a){
            return new myComplex(RealPart+a.RealPart,ImagePart+a.ImagePart);
        }
        myComplex ComplexSub(myComplex a){
            return new myComplex(RealPart-a.RealPart,ImagePart-a.ImagePart);
        }
       myComplex ComplexMulti(myComplex a){
            return new myComplex(RealPart*a.RealPart-ImagePart*a.ImagePart,RealPart*a.ImagePart+a.RealPart*ImagePart);
        }
        myComplex ComplexDiv(myComplex a){
            return new myComplex((RealPart*a.RealPart+ImagePart*a.ImagePart)/(a.RealPart*a.RealPart+a.ImagePart*a.ImagePart),(-RealPart*a.ImagePart+a.RealPart*ImagePart)/(a.RealPart*a.RealPart+a.ImagePart*a.ImagePart));
        }
    //Override Object
     public boolean equals(Object obj){
            if(obj==null)
         return false;
     else {
         myComplex m = (myComplex) obj;
         if (m.RealPart == RealPart && m.ImagePart == ImagePart)
             return true;
         else return false;
     }
        }


    public String toString(){
        String output;
        if(ImagePart==0){
            return output=RealPart+"";
        }
        else if(RealPart==0 && ImagePart!=0){
            return output=ImagePart+"i";
        }
        else if(ImagePart>0) {
            return output=RealPart+"+"+ImagePart+"i";
        }
        else return output=RealPart+""+ImagePart+"i";
    }
    }
重构一:修改类、方法、变量名使符合驼峰规则

myComplex->MyComplex
ComplexXXXX->complexXXXX
RealPart->realPart
ImagePart->imagePart

myComplex(double R,double I){
            RealPart=R;
            ImagePart=I;
        }

MyComplex(double realPart,double imagePart){
            this.realPart=realPart;
            this.imagePart=imagePart;
        }
重构二:添加重写toString方法的“@Override”注释

重构三:为if、while后单个语句添加大括号

在重构后,很多方法名为了符合驼峰规则进行了修改,可能会导致测试代码中的方法名报错,因此最好先进行重构,再编写测试代码。

上传代码到搭档的码云

(三)、完成java密码学相关内容学习

凯撒密码

凯撒密码作为密码学中典型的单表代替密码,加密算法为E:c=m+3(mod26)。
在本实验中,我们将凯撒密码化为一般形式,即我们指定密钥用以加解密。为了方便显示,我将明文、密钥改为程序内部输出。

DES算法

DES算法创建对称密钥加解密步骤:

获取密钥
  1. 获取密钥生成器KeyGenerator kg=KeyGenerator.getInstance("DESede");
  2. 初始化密钥生成器kg.init(168);(指定密钥的长度,如果该步骤省略的话,会根据算法自动使用默认的密钥长度)
  3. 生成密钥SecretKey k=kg.generateKey( );
  4. 通过对象序列化方式将密钥保存在文件中
    运行代码后产生key1.dat,里面存储密钥用于加解密。

打印密钥文件中的内容

进行加密
  1. 从文件中获取密钥
FileInputStream f=new FileInputStream("key1.dat");
ObjectInputStream b=new ObjectInputStream(f);
Key k=(Key)b.readObject( );

2.创建密码器(Cipher对象)
Cipher cp=Cipher.getInstance("DESede");
3.初始化密码器
cp.init(Cipher.ENCRYPT_MODE, k);
4.获取等待加密的明文
String s="Hello World!"; byte ptext[]=s.getBytes("UTF8");
5.执行加密并处理加密结果

byte ctext[]=cp.doFinal(ptext);
FileOutputStream f2=new FileOutputStream("SEnc.dat");
f2.write(ctext);

进行解密
  1. 获取密文
FileInputStream f=new FileInputStream("SEnc.dat");
        int num=f.available();
        byte[ ] ctext=new byte[num];          
        f.read(ctext);

2.获取密钥

FileInputStream  f2=new FileInputStream("keykb1.dat");
int num2=f2.available();
byte[ ] keykb=new byte[num2];          
f2.read(keykb);
SecretKeySpec k=new  SecretKeySpec(keykb,"DESede");

SecretKeySpec类的构造器中第2个参数则指定加密算法。由于keykb1.dat中的密钥原来使用的是DESede算法,因此这里仍旧使用字符串“DESede”作为参数。
3.创建并初始化密码器

Cipher cp=Cipher.getInstance("DESede");
cp.init(Cipher.DECRYPT_MODE, k);

4.执行解密
byte []ptext=cp.doFinal(ctext);

RSA算法

RSA算法分为公钥和私钥两个(一组)密钥,在密码学上已经提及,加密时以公钥加密,解密方用私钥进行解密。

获取密钥对
  1. 创建密钥对生成器KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");
  2. 初始化密钥生成器kpg.initialize(1024);
  3. 生成密钥对KeyPair kp=kpg.genKeyPair( );包含了公钥和私钥一组对信息
  4. 获取公钥和私钥
PublicKey pbkey=kp.getPublic( );
PrivateKey prkey=kp.getPrivate( );

进行加密
  1. 获取公钥
FileInputStream f=new FileInputStream("Skey_RSA_pub.dat");
      ObjectInputStream b=new ObjectInputStream(f);
      RSAPublicKey  pbk=(RSAPublicKey)b.readObject( );
  1. 获取公钥的参数(e, n)
BigInteger e=pbk.getPublicExponent();
BigInteger n=pbk.getModulus();
  1. 获取明文整数(m)
String s="Hello World!";
byte ptext[]=s.getBytes("UTF8");
BigInteger m=new BigInteger(ptext);
  1. 执行计算 BigInteger c=m.modPow(e,n);

进行解密

  1. 读取密文
BufferedReader in= 
          new BufferedReader(new InputStreamReader(
new FileInputStream("Enc_RSA.dat")));
String ctext=in.readLine();
BigInteger c=new BigInteger(ctext);
  1. 获取私钥
FileInputStream f=new FileInputStream("Skey_RSA_priv.dat");
ObjectInputStream b=new ObjectInputStream(f);
RSAPrivateKey prk=(RSAPrivateKey)b.readObject( );
  1. 获取私钥的参数(d, n)
BigInteger d=prk.getPrivateExponent( );
BigInteger n=prk.getModulus( ); 
  1. 执行计算BigInteger m=c.modPow(d,n);
  2. 计算明文整型数对应的字符串
byte[] mt=m.toByteArray();
for(int i=0;i<mt.length;i++){
       System.out.print((char) mt[i]);
}

实验总结与感想

编码标准阶段

在实验的这一阶段主要是尝试运用alibaba编码规约扫描插件,惊奇的发现原来平日里自己写的代码原来有这么多不规范的地方。娄老师在博客中说代码是给人读的,我们在敲代码写程序的时候,不是简单的将一件事完成就算结束了,而是要在正确的基础上规范自己的书写和标准,即方便其他人的阅读也能方便自己的纠错。虽然规范与否短时间内看不出什么非常明显的优势,但是养成一个良好的习惯最终一定会润物无声地对我们如同臂助。
同时,我第一次使用了code菜单栏,发现了许多简单的功能,运用它们省时省力,可以节省许多不必要的时间。我们使用IDEA本就是源于它的高效,如果对这些功能不加以运用无异于买椟还珠。所以在今后的学习中,我们应该不断学习IDE的使用,掌握它的功能,尤其要熟练那些帮助非常的的功能的快捷键。

结对阶段

结对的思想早在结对编程任务就已有学习。在此次实验中我的搭档依然选择了结对伙伴。在结对过程中难免会遇到意见不同的情况,但是有一句话说的好有时候,不同意见也是健康关系的重要组成部分,意见不同也可以看作是找寻最佳方案的良机,大家都坚持自己的思想,势必会最终得到一个更加完美的解决,值得把握。

密码学相关内容学习阶段

在这一阶段,我们学习了许多密码学课上学到的算法的编程实现,例如凯撒密码、DES算法、RSA算法。我们在学校一科一科的学习,往往自动的将它们割裂开来。学密码学是密码学,学数据结构是数据结构,稍微结合一点编程的操作就觉得难比登天。其实这是不对的。娄老师倡导我们做中学,数据结构张岩老师说:计算机毫无智能可言,娄老师在博客中引用了侯捷老师的方法论会用,明理,扩展明理之前要会用。其实把这几话结合起来,我觉得就是这项任务的用意。在学一样东西,首先尝试使用,再深入理解达到明理。我们在学密码学,可以尝试用编程的方法使用它,计算机做的是你教给它的东西,它成功的实现了一个算法,就代表你的思路正确,你就可以在正确的思路上深入挖掘。前几次的密码学实验都可以用java实现,因为现阶段中,java编程也是我们要学习的内容。

码云链接

自己码云链接
搭档的码云链接

标签:ImagePart,20175308,密钥,敏捷,new,XP,RealPart,myComplex
来源: https://www.cnblogs.com/darklord0604/p/10805792.html