标签:
北京电子科技学院(BESTI)
实 验 报 告
课程: Java 班级:1352 姓名:黄伟业 学号:20135215
成绩: 指导教师:娄嘉鹏 实验日期:2015.6.2
实验密级: 预习程度: 实验时间:15:30~18:00
仪器组次:37 必修/选修:选修 实验序号:(三)
实验名称:敏捷开发与XP实践
实验目的:
1.XP基础
2.XP核心实践
3.相关工具
实验要求:
1.没有Linux基础的同学建议先学习《Linux基础入门(新版)》《Vim编辑器》 课程
2.完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。报告可以参考范飞龙老师的指导
3. 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。
实验步骤:
1、软件工程
软件工程是把系统的、有序的、可量化的方法应用到软件的开发、运营和维护上的过程。
软件开发流程的目的是为了提高软件开发、运营、维护的效率,并提高软件的质量、用户满意度、可靠性和软件的可维护性。软件开发很重要的一点不是看你能对多少理论讲的头头是道,还要看你对相关工具应用的如何,比如Java中单元测试要和JUnit的应用结合起来,建模要和Umbrello或StarUML的应用结合起来。编程学习是一个习而学的过程。 一个常见的公式是:软件工程=开发流程+工具 邹欣老师给出的两个公式:软件=程序+软件工程和软件企业=软件+商业模式
2、极限编程(eXtreme Programming,XP)
是一种全新而快捷的软件开发方法。XP团队使用现场客户、特殊计划方法和持续测试来提供快速的反馈和全面的交流:
XP软件开发是什么样的通过 XP准则来表达:
一项实践在XP环境中成功使用的依据通过XP的法则呈现,包括:快速反馈、假设简单性、递增更改、提倡更改、优质工作。
XP软件开发的基石是XP的活动,包括:编码、测试、倾听、设计。
(二)编码标准
编写代码一个重要的认识是“程序大多时候是给人看的”,编程标准使代码更容易阅读和理解,甚至可以保证其中的错误更少。编程标准包含:具有说明性的名字、清晰的表达式、直截了当的控制流、可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性。
下面来看一个例子:
程序没有最基本的缩进,让人读起来很费劲,这个问题在Eclipse中比较容易解决,我们单击Eclipse菜单中的source(源码)->Format(格式) 或用快捷键Ctrl+Shift+F就可
以按Eclipse规定的规范缩进,效果如下:
代码标准中很重要的一项是如何给包、类、变量、方法等标识符命名,能很好的命名可以让自己的代码立马上升一个档次。Java中的一般的命名规则有:
l 要体现各自的含义
l 包、类、变量用名词
l 方法名用动宾
l 包名全部小写,如:io,awt
l 类名第一个字母要大写,如:HelloWorldApp
l 变量名第一个字母要小写,如:userName
l 方法名第一个字母要小写:setName
l ...
标识符名字应当直观且可以拼读,可望文知意,不必进行“解码”,一般采用英文单词或其组合,便于记忆和阅读,切忌使用汉语拼音来命名,用词要准确。
标识符的长度“min-length && max-information”的原则,比如:maxVal 比maxValueUntilOverflow要好些,可以通过去元音法把变量名变短,如returnValue->rtnVal ,message->msg;一般全局变量用具有说明性的名字,局部变量用短名字:单字符的名字,常见的如i,j,k等用作局部变量。
其他的可以参考邹欣老师写的代码规范与代码复审.
关于代码标准,可以遵循以下原则:
有一些公司比如Google公开了自己的编码标准,可以作为学习不错的参考,大家参考一下范飞龙老师写的代码规范&代码风格,有兴趣的可以尝试如何在Eclipse中实践Google Java Style(中文版),也就是说如何做到“按一下快捷键Ctrl+Shift+F就可以让自己的代码符合Google Java Style(中文版)的要求”,完成后单独写一篇Blog,有加分的。
(三)结对编程
结对编程是XP中的重要实践。在结对编程模式下,一对程序员肩并肩、平等地、互补地进行开发工作。他们并排坐在一台电脑前,面对同一个显示器,使用同一个键盘、同一个鼠标一起工作。他们一起分析,一起设计,一起写测试用例,一起编码,一起做单元测试,一起做集成测试,一起写文档等。 结对编程中有两个角色:
l 驾驶员(Driver)是控制键盘输入的人。
l 领航员(Navigator)起到领航、提醒的作用。
重点是:
l 驾驶员:写设计文档,进行编码和单元测试等XP开发流程。
l 领航员:审阅驾驶员的文档、驾驶员对编码等开发流程的执行;考虑单元测试的覆盖率;思考是否需要和如何重构;帮助驾驶员解决具体的技术问题。
l 驾驶员和领航员不断轮换角色,不要连续工作超过一小时,每工作一小时休息15分钟。领航员要控制时间。
l 主动参与。任何一个任务都首先是两个人的责任,也是所有人的责任。没有“我的代码”、“你的代码”或“他/她的代码”,只有“我们的代码”。
l 只有水平上的差距,没有级别上的差异。两人结对,尽管可能大家的级别资历不同,但不管在分析、设计或编码上,双方都拥有平等的决策权利。。
(四)版本控制
XP的集体所有制意味着每个人都对所有的代码负责;这一点,反过来又意味着每个人都可以更改代码的任意部分。结对编程对这一实践贡献良多:借由在不同的结对中工作,所有的程序员都能看到完全的代码。集体所有制的一个主要优势是提升了开发程序的速度,因为一旦代码中出现错误,任何程序员都能修正它。 这意味着代码要放到一个大家都能方便获取的地方,我们叫代码仓库。这引出另外一个话题叫版本控制(Version Control)。
不论是对于团队还是个体,版本控制都提供了很多好处。
l 版本控制提供项目级的 undo(撤销) 功能: 没有什么事情是终结版本, 任何错误必须很容易回滚。 假设你在使用世界上最复杂的文字处理系统。 它具备了所有的能想到的功能,就是没有支持 DELETE(删除) 键。想象你打字的时候得多么的谨慎和缓慢吧, 特别是一篇超大的文档的快临近末尾的时候, 一个不小心就要重头再来(试想你选中所有的文字, 不小心按了 DELETE 键, 因为没有撤销功能,只好重新录入)。编辑文字和版本控制相同,任何时候都需要回滚,无论是一个小时, 一天, 还是一周, 这让你的团队工作自由快速的工作, 而且对于修正错误也非常自信。
l 版本控制允许多人在同一代码上工作, 只要遵守一定的控制原则就行。 再也不会发生诸如一个人覆盖了另一个人编辑的代码,导致那个人的修改无效这样的情况。
l 版本控制系统保存了过去所作的修改的历史记录。如果你遭遇到一些惊讶的代码,通过版本控制系统可以很容易找出是谁干的, 修改了什么, 修改的时间, 如果幸运的话,还能找出原因。
l 版本控制系统还支持在主线上开发的同时发布多个软件版本。在软件发布的时候也不需要整个团队的停止工作,不需要冻结代码。
l 版本控制也是项目级的时间机器,你可以选择任何一个时间, 精确地查看项目在当时的情况。 这对研究非常有用, 也是重现以前某个有问题的发布版本的基础。
l 流行的版本控制工具有CVS,SVN,Git等,更多的可以参考这里。Git是Linus除了Linux操作系统外的另外一个重要发明。
克隆其他用户代码仓库只需要知道对方的仓库链接:$ git clone http://git.shiyanlou.com/[对方的专属用户名]/[课程代码仓库名]
以HelloWorld的例子:
$ cd /home/shiyanlou/Code/shiyanlou_cs212
l # 修改代码文件
l # 添加修改文件
l $ git add 所有修改的文件
l # 提交到环境中本地代码仓库
l $ git commit -m ‘本次修改的描述‘
l # push到git.shiyanlou.com,无需输入密码
l $ git push
(五)重构
1. 概念
重构(Refactor),就是在不改变软件外部行为的基础上,改变软件内部的结构,使其更加易于阅读、易于维护和易于变更。
2. eclipse中Refactor
重新命名:Rename
封装成员变量:Encapsulate Field...
抽象方法:Extract Method...
这个类,类名,方法名和方法的参数名都有问题,没有注释的话是无法理解代码的。我们可以使用Eclipse中的重构功能来改名。修改方法是,用鼠标单击要改的名字,选择Eclipse中菜单中的Refactor->Rename...: 重构完的效果如下:
3.实用的方法
4. 完整的重构流程包括:
从版本控制系统代码库中Check out code→读懂代码(包括测试代码)→发现bad smell→Refactoring→运行所有的Unit Tests→往代码库中Check in code
(六)实践项目
1. 以结对编程的方式编写一个软件,Blog中要给出结对同学的Blog网址,可以拍照展现结对编程情况,可以参考一下其他学校的作业
2.记录TDD和重构的过程,测试代码不要少于业务代码,Eclipse中refactor菜单下的重构技能不要少于5个
3.团队代码要使用git在实验楼中托管,要使用结对同学中的一个同学的账号托管。
4. 程序要有GUI界面,参考用户界面和用户体验
5.程序功能从豌豆荚游戏中选择一款用Java实现,注意:团队之间项目不能有重复,课代表协调一下。
6.实验报告中统计自己的PSP(Personal Software Process)时间
产品代码及截图如下:
package dj;
import java.awt.*; import java.awt.event.*; import java.io.*;
import javax.swing.*;
public class mainFrm extends JFrame implements KeyListener, Runnable{ Button btn_start=new Button(); int moveDir=0; int i=0; int x=100; int y=400; public int dr=1; int btm=0; int base=200; boolean isLive=true; JMenuBar mb=new JMenuBar(); JMenu jm=new JMenu("菜单"); JMenuItem jm1=new JMenuItem("开始"); JMenuItem jm2=new JMenuItem("暂停"); JMenuItem jm3=new JMenuItem("得分记录"); JMenuItem jm4=new JMenuItem("退出"); boolean isStart=false; Board bd[]=new Board[10]; JLabel lbl_score=new JLabel("score:"); JLabel lbl_level=new JLabel("level:"); int level=1; int score=0;
boolean moveBg=false; JLabel lbl_img=new JLabel(new ImageIcon("man.jpg")); JLabel lbl_bd1=new JLabel(new ImageIcon("board.jpg")); JLabel lbl_bd2=new JLabel(new ImageIcon("board.jpg")); JLabel lbl_bd3=new JLabel(new ImageIcon("board.jpg")); JLabel lbl_bd4=new JLabel(new ImageIcon("board.jpg")); JLabel lbl_bd5=new JLabel(new ImageIcon("board.jpg")); JLabel lbl_bd6=new JLabel(new ImageIcon("board.jpg")); JLabel lbl_bd7=new JLabel(new ImageIcon("board.jpg")); JLabel lbl_bd8=new JLabel(new ImageIcon("board.jpg")); JLabel lbl_bd9=new JLabel(new ImageIcon("board.jpg")); JLabel lbl_bd0=new JLabel(new ImageIcon("board.jpg")); mainFrm(){ jm.add(jm1); jm.add(jm2); //jm.add(jm3); jm.add(jm4); setJMenuBar(mb); mb.add(jm); setTitle("DoodleJump"); setSize(350,600); setLocation(300,100); setBackground(Color.white); setVisible(true); setLayout(null); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0);}}); jm3.addActionListener(new ActionListener(){ public void actionPerformed (ActionEvent e){ } }); jm4.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { System.exit(0);}}); jm1.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { isStart=true;}}); jm2.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { isStart=false;}}); lbl_score.setSize(100,30); lbl_score.setLocation(250, 0); lbl_level.setSize(100,30); lbl_level.setLocation(20, 0); bd[0]=new Board(100); bd[1]=new Board(120); bd[2]=new Board(170); bd[3]=new Board(230); bd[4]=new Board(280); bd[5]=new Board(330); bd[6]=new Board(370); bd[7]=new Board(400); bd[8]=new Board(440); bd[9]=new Board(480); btn_start.setLocation(350, 50); btn_start.setSize(100, 30); btn_start.addKeyListener(this); lbl_img.setLocation(0, 0); lbl_img.setSize(64, 60); lbl_bd1.setLocation(bd[1].x, bd[1].y); lbl_bd1.setSize(63, 19); lbl_bd2.setLocation(bd[2].x, bd[2].y); lbl_bd2.setSize(63, 19); lbl_bd3.setLocation(bd[3].x, bd[3].y); lbl_bd3.setSize(63, 19); lbl_bd4.setLocation(bd[4].x, bd[4].y); lbl_bd4.setSize(63, 19); lbl_bd5.setLocation(bd[5].x, bd[5].y); lbl_bd5.setSize(63, 19); lbl_bd6.setLocation(bd[6].x, bd[6].y); lbl_bd6.setSize(63, 19); lbl_bd7.setLocation(bd[7].x, bd[7].y); lbl_bd7.setSize(63, 19); lbl_bd8.setLocation(bd[8].x, bd[8].y); lbl_bd8.setSize(63, 19); lbl_bd9.setLocation(bd[9].x, bd[9].y); lbl_bd9.setSize(63, 19); lbl_bd0.setSize(63, 19); lbl_bd0.setLocation(bd[0].x, bd[0].y); add(btn_start); addKeyListener(this); add(lbl_img); add(lbl_bd1); add(lbl_bd2); add(lbl_bd3); add(lbl_bd4); add(lbl_bd5); add(lbl_bd6); add(lbl_bd7); add(lbl_bd8); add(lbl_bd9); add(lbl_bd0); add(lbl_score); add(lbl_level); repaint(); }
public static void main(String[] args) { mainFrm mf=new mainFrm(); Thread t1=new Thread(mf); t1.start(); }
public int funT(int x){ return x*x/50; } int r=1; int t=0; int bd_base[]=new int[10]; public void run() { for(int i=0;i<10;i++){ bd_base[i]=bd[i].y; } int score_dr=10000; lbl_level.setText("level:"+level); while(true){ if(isStart==true) { dis(); ifJump(); t+=r; if(kp==true){//按键则左右移动。 x+=dr; } if(x<-30) x=300; if(x>300) x=-30; if(moveBg==false){//人物 跳跃 y=base+funT(t); if(score>score_dr){ level++; score_dr+=10000; lbl_level.setText("level:"+level); } } else{ int aaa=200-(200+base-y)-funT(t); for(int i=0;i<10;i++){ bd[i].y=bd_base[i]+aaa; score++; lbl_score.setText("Score:"+score/10); } } ifIsDead(); lbl_img.setLocation(x, y);//刷新屏幕 lbl_bd1.setLocation(bd[1].x, bd[1].y); lbl_bd2.setLocation(bd[2].x, bd[2].y); lbl_bd3.setLocation(bd[3].x, bd[3].y); lbl_bd4.setLocation(bd[4].x, bd[4].y); lbl_bd5.setLocation(bd[5].x, bd[5].y); lbl_bd6.setLocation(bd[6].x, bd[6].y); lbl_bd7.setLocation(bd[7].x, bd[7].y); lbl_bd8.setLocation(bd[8].x, bd[8].y); lbl_bd9.setLocation(bd[9].x, bd[9].y); lbl_bd0.setLocation(bd[0].x, bd[0].y); try {//停顿 20ms Thread.sleep(7); } catch (InterruptedException e) { e.printStackTrace(); } if(t<=-100){//t小于-100 t++ r=-r; } if(t<0)moveDir=0;//t小于 0 跳棋状态 反之 下降状态。 else { moveDir=1; } if(y<199&&moveDir==0&&moveBg==false){//y小于一定程度的时候背景开始动,任务则在y的位置停止 moveBg=true; } else if(t==0&&moveBg==true) { moveBg=false; base=200; for(int i=0;i<10;i++){ bd_base[i]=bd[i].y; } } } } }
boolean kp = false; boolean isMove = false; public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if(isMove==false){ switch(e.getKeyCode()) { case KeyEvent.VK_LEFT:{ dr=-2; break; } case KeyEvent.VK_RIGHT:{ dr=2; break;} case KeyEvent.VK_UP:{ if(moveDir==1){ dr=0; t=-100; r=-1; btm=base+200-y; base=base-btm; } break; } } } kp=true; isMove=true; }
public int findMix(){ int min=bd[0].y; for(int i=1;i<10;i++){ if(bd[i].y<min) min=bd[i].y; } System.out.println(min); return min; } public void dis(){ for(int i=0;i<10;i++){ if(bd[i].y>500) { bd[i].newPosition(findMix()-170-level); bd_base[i]=bd[i].y; System.out.println("----------- "+i); } } } public void ifIsDead(){ if(y>600&&isLive==true){ isStart=false; System.out.print("dead"); isLive=false; JOptionPane.showMessageDialog(null,"game over","结束",JOptionPane.ERROR_MESSAGE); bd[0]=new Board(100); bd[1]=new Board(120); bd[2]=new Board(170); bd[3]=new Board(230); bd[4]=new Board(280); bd[5]=new Board(330); bd[6]=new Board(370); bd[7]=new Board(400); bd[8]=new Board(440); bd[9]=new Board(480); bd[8].x=bd[9].x; for(int i=0;i<10;i++){ bd_base[i]=bd[i].y; } x=bd[9].x; y=400; isStart=true; isLive=true; } } public void ifJump(){ int width=45; int height=10; for(int i=0;i<10;i++){ if(moveDir==1&&(x>bd[i].x-width-5&&x<bd[i].x+width-10&&y>bd[i].y-height-40&&y<bd[i].y+height-40)){ moveDir=0; t=-100; r=1; btm=base+200-y; base=base-btm; } } } public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub // System.out.println(e.getKeyChar()); kp = false; isMove=false; } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } }
游戏运行结果截图如下图:
游戏运行结果截图如下图:
PSP时间统计
步骤 |
耗时 |
百分比 |
需求分析 |
25min |
8.2% |
设计 |
80min |
26.2% |
代码实现 |
120min |
39.3% |
测试 |
50min |
18% |
分析总结 |
25min |
8.2% |
7.实验总结
通过本次试验我对Java有了更深的认识,了解了它的许多功能都非常实用,在以后的练习中将多加练习。通过Java编写的小程序让我对Java更加“佩服”,由于自己的
水平太有限,所以从网上参考了许多,让我了解到学习课本的知识是远远不足,所以在今后的任然需要努力。
结对同学blog地址:http://www.cnblogs.com/lv-20135229/p/4553600.html
http://www.cnblogs.com/lv-20135229/p/4553600.html
标签:
原文地址:http://www.cnblogs.com/1551127024hwy/p/4570469.html