实验三:敏捷开发与XP实践
Java实验三报告
一、 实验内容
(一)敏捷开发与XP
内容:1.敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法。
2.极限编程(eXtreme Programming,XP)是一种全新而快捷的软件开发方法。
要点: 1. XP软件开发的基石是XP的活动,包括:编码、测试、倾听、设计。
2. 我们关注其中的编码标准,结对编程,代码集体所有,测试,重构等实践。(如实验二中的TDD)
(二)编码标准
内容:编程标准使代码更容易阅读和理解,甚至可以保证其中的错误更少。编程标准包含:具有说明性的名字、清晰的表达式、直截了当的控制流、可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性。
学习:
1. 软件辅助修改:在eclipse中,用source->Format进行格式规范;
2. 自己命名:包名全部小写,如: io ;类名第一个字母要大写,如:HelloWorldApp;等
(三)结对编程
内容:在结对编程模式下,一对程序员肩并肩、平等地、互补地进行开发工作。其中的角色分配为驾驶员(控制键盘输入),领航人(起到领航、提醒作用)。
(四)版本控制
摘要:版本控制提供项目级的 undo(撤销) 功能;• 版本控制允许多人在同一代码上工作;• 版本控制系统保存了过去所作的修改的历史记录;具体步骤如下——
# 添加修改文件
$ git add 所有修改的文件
# 提交到环境中本地代码仓库
$ git commit -m '本次修改的描述'
# push到git.shiyanlou.com,无需输入密码
$ git push
学习:按照要求指导,逐步在实验楼中完成,截图如下:
git log之后的结果如下:
(五)重构
摘要:重构(Refactor),就是在不改变软件外部行为的基础上,改变软件内部的结构,使其更加易于阅读、易于维护和易于变更 。学习:尝试Encapsulate Field(封装)功能:
原图:
使用后:
清除代码重复的重构方法:同一class中重复,则提炼重复;互为兄弟的模块内重复,则提炼到父类中;不同的方法做同样的事,则选择更清晰的算法而将另外的算法清除;
以StudentTest为例,图如下:
此外,在重构代码后,还有一个必不可少的步骤即进行新一轮的测试,即产品代码仍要通过之前的所有测试。
(六)实践项目
(同伴20135216刘蔚然的博客:http://www.cnblogs.com/lwr-/)
1.综述
由于我们小组之前没有编写过具有独立功能和可操作图形化界面程序。因而我们采取“先学习,后操作;边操作,边变通”的实验思路。具体方法是:研读要求—学习代码要素—复习TDD内容—构建测试程序—检查测试程序—测试产品代码—修改产品代码—重新检查产品代码—完成实验报告。在这一过程中,我们对各方面内容都进行了详细记录(未在实验楼中进行托管和git)
团队由两名成员组成,详细分工为:
20135216刘蔚然:负责前期学习的整理工作,将java代码进行必要注释,并对TDD内容进行补充;进行后期测试
20135211李行之:负责中期的测试代码开发;进行后期测试
2.研读要求与自我学习(20135211)
1.TDD(Test Driven Development, 测试驱动开发),
TDD的一般步骤如下:
- 明确当前要完成的功能,记录成一个测试列表
- 快速完成编写针对此功能的测试用例
- 测试代码编译不通过(没产品代码呢)
- 编写产品代码
- 测试通过
- 对代码进行重构,并保证测试通过(重构下次实验练习)
- 循环完成所有功能的开发
2. 测试类具体操作:把鼠标放到项目名上,单击右键,在弹出的菜单中选定New->Source Folder新建一个测试目录test;把鼠标放到test目录上,单击右键,在弹出的菜单中选定New->JUnit Test Case新建一个测试用例类
3.实验要求要点为:程序要有GUI界面,参考用户界面和用户体验;记录TDD和重构的过程,测试代码不要少于业务代码
4.补充学习内容
Java语句(具体见程序注释)
JUnit用法:
1) http://blog.csdn.net/stevenhu_223/article/details/8269157 Java单元测试JUnit
2) http://www.blogjava.net/qileilove/archive/2013/10/15/405004.html 使用JUnit进行Java相关测试
- 设计思路(20135211,20135216)
首先,根据用户需求合理分配代码密度,即:
- 用户直接操作(点击运行)的程序为主控程序,仅包含对与用户接触的窗口的定义语句和相关函数调用;
- 后台处理图形化界面的语句组成控制程序,包括:对话框算法、蛇和果实(对象)的位置显示和移动算法、对象位置记录、暂停键及停止条件函数等。
其次,对具体程序进行编写:
- MainClass函数:继承JFrame类,调用ControlSnake类;定义窗口大小和位置
- ControlSnake函数:继承JPanel类;定义贪吃蛇的坐标位置和果实坐标位置,定义随机数发生器等;建立主函数接收键盘传入并转换成keyCode,执行对应操作;建立Paint函数构造窗口;建立Action函数进行动画演示(包括调用随机数发生函数产生伪随机序列,确定果实位置)
最后,对难点进行攻克:
- 如何在蛇碰到边界后产生对话框提示用户重新开始?
参阅资料后,决定在Action函数中再加入语句解决此问题,主要思想是在用专门的函数记录是否“碰到边界”(坐标的范围)这一状态,并返回一个Boolean类型变量;根据此变量值来判断是否跳出对话框;若跳出对话框,则要清空之前的记录重新开始
4.进行代码注释(20135216)
MainClass函数
package resource;
import java.awt.*;
import javax.swing.*;
@SuppressWarnings("serial")//注释处的所有警告都忽视
public class MainClass extends JFrame {
ControlSnake control;
Toolkit kit;//所有实际应用的抽象窗口工具包的父类
Dimension dimen;//压缩了有整数精确度的组件
public static void main(String[] args) {
new MainClass("my snake");
}
public MainClass(String s) {
super(s);
control = new ControlSnake();//新的ControlSnake类
control.setFocusable(true);
kit = Toolkit.getDefaultToolkit();
dimen = kit.getScreenSize();//获取屏幕尺寸
add(control);//添加control
setLayout(new BorderLayout());
setLocation(dimen.width / 3, dimen.height / 3);// 挪位置,dimen.width/3,dimen.height/3
setSize(FWIDTH, FHEIGHT);//定格操作窗口大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
}
public static final int FWIDTH = 315;
public static final int FHEIGHT = 380;
}
ControlSnake函数
package resource;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;
import java.util.Random;
@SuppressWarnings("serial")
public class ControlSnake extends JPanel implements ActionListener {
//JPanel类用于为小内容提供简单窗口,ActionListener为对象提供添加动作的方法
Random rand;
//Random,用48bit的种子产生伪随机序列
ArrayList<Point> list, listBody;
//ArrayList<Point>,类似于二维数组,声明了两个泛型对象
String str, str1;
static boolean key;
int x, y, dx, dy, fx, fy, flag;
int snakeBody;
//控制蛇的长度
int speed;
public ControlSnake()
{
snakeBody = 1;
str = "上下左右方向键控制 P键暂停...";
str1 = "现在的长度为:" + snakeBody;
key = true;
flag = 1;
speed = 700;
rand = new Random();//创造一个新的随机数产生器
list = new ArrayList<Point>();//创造一个初始容量为10的数列
listBody = new ArrayList<Point>();
x = 5;
y = 5;
list.add(new Point(x, y));//在坐标空间中创建并初始化一个新的点
listBody.add(list.get(0));//list.get(0),返回在list列中0位置的元素
dx = 10;
dy = 0;
fx = rand.nextInt(30) * 10 + 5;// rand.nextInt(30),返回一个在0——30内的随机数
fy = rand.nextInt(30) * 10 + 5;// 2
setBackground(Color.WHITE);//为窗口添加背景色
setSize(new Dimension(318, 380));//重新定义窗口的高和宽
final Timer time = new Timer(speed, this);
time.start();
//timer类,在指定时间间隔触发一个或多个 ActionEvent
addKeyListener(new KeyAdapter()
{
//KeyAdapter(),用于接收键盘传来的事件的抽象类
public void keyPressed(KeyEvent e)
{
//KeyEvent,使键盘输入转化成对应对象
if (e.getKeyCode() == 37) {//getKeyCode(),将键盘输入转化成对应的整形键码
dx = -10;
dy = 0;
} else if (e.getKeyCode() == 38) {
dx = 0;
dy = -10;
} else if (e.getKeyCode() == 39) {
dx = 10;
dy = 0;
} else if (e.getKeyCode() == 40) {
dx = 0;
dy = 10;
} else if (e.getKeyCode() == 80) {
if (flag % 2 == 1) {
time.stop();
}
if (flag % 2 == 0) {
time.start();
}
flag++;
}
}
});
}
public void paint(Graphics g) {//Graphics,所有环境算法基础类,允许应用在已有组件上进行绘制
g.setColor(Color.WHITE);
g.fillRect(0, 0, 400, 400);//指定一个以setColor返回值为底色的长方形,具体参数为x,y
g.setColor(Color.DARK_GRAY);
g.drawLine(3, 3, 305, 3);//在点(3,3)和(305,3)之间用当前色填充一条线
g.drawLine(3, 3, 3, 305);
g.drawLine(305, 3, 305, 305);
g.drawLine(3, 305, 305, 305);
g.setColor(Color.PINK);
for (int i = 0; i < listBody.size(); i++) {//listBody.size(),返回当前list的元素个数
g.fillRect(listBody.get(i).x, listBody.get(i).y, 9, 9);
}//控制蛇的长度
g.fillRect(x, y, 9, 9);//蛇的长度最大为9
g.setColor(Color.ORANGE);
g.fillRect(fx, fy, 9, 9);//随机显示果实
g.setColor(Color.DARK_GRAY);
str1 = "现在的长度为:" + snakeBody;
g.drawString(str, 10, 320);//在图形化界面中显示字符串
g.drawString(str1, 10, 335);
}
public void actionPerformed(ActionEvent e) {
x += dx;
y += dy;
if (makeOut() == false) {//见最后的函数,用于排除超出图形界面的不合法输出
JOptionPane.showMessageDialog(null, "重新开始......");
//跳出对话框,显示“重新开始”
speed = 700;
snakeBody = 1;
x = 5;
y = 5;
list.clear();//清空数列
list.add(new Point(x, y));//加入新元素
listBody.clear();
listBody.add(list.get(0));
dx = 10;
dy = 0;
}
addPoint(x, y);
if (x == fx && y == fy) {//即“蛇吃到果实”
speed = (int) (speed * 0.8);// 速度增加参数
if (speed < 200) {
speed = 100;
}
fx = rand.nextInt(30) * 10 + 5;// 2
fy = rand.nextInt(30) * 10 + 5;// 2
snakeBody++;// 2
} // 2
repaint();//重新进行
}
public void addPoint(int xx, int yy) {
// 动态的记录最新发生的50步以内的移动过的坐标
// 并画出最新的snakeBody
if (list.size() < 100) {// 蛇身长度最长为100
list.add(new Point(xx, yy));
} else {
list.remove(0);
list.add(new Point(xx, yy));
}
if (snakeBody == 1) {
listBody.remove(0);
listBody.add(0, list.get(list.size() - 1));
} else {
listBody.clear();
if (list.size() < snakeBody) {
for (int i = list.size() - 1; i > 0; i--) {
listBody.add(list.get(i));
}
} else {
for (int i = list.size() - 1; listBody.size() < snakeBody; i--) {
listBody.add(list.get(i));
}
}
}
}
public boolean makeOut() {
if ((x < 3 || y < 3) || (x > 305 || y > 305)) {
return false;
}
for (int i = 0; i < listBody.size() - 1; i++) {
for (int j = i + 1; j < listBody.size(); j++) {
if (listBody.get(i).equals(listBody.get(j))) {
return false;
}
}
}
return true;
}
}
4. 代码测试及思路(20135211)
测试思路:
1.当图形超出界面时,应跳出对话框提示用户重新开始
2.当且仅当按下P键(大写锁定)时,程序停止
代码如下
//import java.util.Timer;
import org.junit.Test;
import resource.ControlSnake;
import junit.framework.TestCase;
//import static org.junit.Assert.*;
//import static org.hamcrest.Matcher.*;
public class ControlSnakeTest extends TestCase {
@Test
public void test()
{
//Timer time = new Timer(speed, this);
ControlSnake controlSnake = new ControlSnake();
assertEquals(true, controlSnake.makeOut());//检测makeOut是否返回值正常
//assertEquals(new String(), );
}
}
5. 过程记录(20135211)
图1 初始命名有误
图2 重命名
图3 格式不规范
图4 测试类使用
6.时间统计
因为网络问题实验楼上的任务占用了很多不必要的时间,浪费了大量的精力和财务(话费),希望老师能对实验方面的教学进行一定的修改。
在实践部分,研读调试游戏代码占用了巨大的时间,是本次实验中最耗时也是最有意义的地方。
7.实验感悟
本次实验,尤其是通过对实验内容四,五的学习,让我对Eclipse的使用有了更多的了解,为以后规范代码提供了很大的帮助。
并且本次实践通过观看网上的游戏代码,对我今后的编程有很大的启发,对程序有了更深刻的认识。
实验三:敏捷开发与XP实践的更多相关文章
- 20145213《Java程序设计》实验三敏捷开发与XP实践
20145213<Java程序设计>实验三敏捷开发与XP实践 实验要求 1.XP基础 2.XP核心实践 3.相关工具 实验内容 1.敏捷开发与XP 软件工程是把系统的.有序的.可量化的方法 ...
- 20145308刘昊阳 《Java程序设计》实验三 敏捷开发与XP实践 实验报告
20145308刘昊阳 <Java程序设计>实验三 敏捷开发与XP实践 实验报告 实验名称 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 统计的PSP(Personal ...
- JAVA课程实验报告 实验三 敏捷开发与XP实践
北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1353 姓名:韩玉琪 学号:20135317 成绩: 指导教师:娄嘉 ...
- 20145225《Java程序设计》 实验三 "敏捷开发与XP实践"
20145225<Java程序设计> 实验三 "敏捷开发与XP实践" 实验报告 实验内容 使用 git 上传代码 使用 git 相互更改代码 实现代码的重载 git 上 ...
- 20145215实验三 敏捷开发与XP实践
20145215实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验步骤 (一)敏捷开发与XP 软件工程是把系统的.有序的.可量化的方法应用到软件的开发.运营和维护上的过程.软 ...
- 20145325张梓靖 实验三 "敏捷开发与XP实践"
20145325张梓靖 实验三 "敏捷开发与XP实践" 程序设计过程 实验内容 使用 git 上传代码 git上传中遇到的问题 使用 git 相互更改代码 实现代码的重构 git ...
- 20162311 实验三 敏捷开发与XP实践 实验报告
20162311 实验三 敏捷开发与XP实践 实验报告 实验内容 一.研究学习IDEA中的Code菜单 使用Code ->Reformate Code功能将以下代码格式化 public clas ...
- 2018-2019-20175205 实验三敏捷开发与XP实践《Java开发环境的熟悉》实验报告
2018-2019-20175205 实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)>&l ...
- 20175314 实验三 敏捷开发与XP实践
20175314 实验二 Java面向对象程序设计 一.实验内容 XP基础 XP核心实践 相关工具 二.实验步骤 (一)代码格式化 创建"175314.exp3"项目,在该项目下创 ...
- #实验三 敏捷开发与XP实践---实验报告
一.实验三 敏捷开发与XP实践-1 1.实验要求 -实验三 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成I ...
随机推荐
- 联想拯救者s15k重装w10系统教程
目的:1.自己平常健忘,且总是要重装系统,2.给看到此篇文章的人一点参考 ps:联想拯救者s15k系列,带有两个硬盘,一个是装系统的硬盘,大小约120G,一个是资料盘,大小约900G,系统重装在小硬盘 ...
- Msys/MinGW与Cygwin/gcc
一. MinGW MinGW 官方网站为 http://www.mingw.org/ MinGW,即 Minimalist GNU For Windows(GCC compiler suite).它是 ...
- Hive HBase Integration 集成
官方文档:https://cwiki.apache.org/confluence/display/Hive/HBaseIntegration 1.在hive/lib目录下找到hive-hbase-ha ...
- jquery animate() Alternate 语法
前段时间在使用jQuery的animate() 函数时候用到Alternate方式.主要是要让数字自增到指定大小,且能看见数字增加过程. 一般使用如下方式: function autoPlusAnim ...
- RMAN 与control文件的关系
试验: SQL> oradebug setmypid;Statement processed.SQL> 接着,进行backup: RMAN> list backup; using t ...
- Android——蓝牙利用RSSI进行距离测算
算法: /** * 功能:根据rssi计算距离 * Created by liuhuichao on 2017/1/17. */ public class RssiUtil { //A和n的值,需要根 ...
- 5469: [FJOI2018]领导集团问题
5469: [FJOI2018]领导集团问题 链接 题意: 要求在一棵树内选一个子集,满足子集内的任意两个点u,v,如果u是v的祖先,那么u的权值小于等于v. 分析: dp[u][i]表示在u的子树内 ...
- SpringCloud-初识微服务(一)
前言 本篇文章简单介绍一下什么是微服务.微服务的优点.SpringCloud的微服务架构核心组件选型等: 一.什么是微服务? 微服务的提出者Martin Fowler是这样描述微服务的(原文:http ...
- burpsuite 抓取https 证书问题
一定要按照步骤来,先导入burp初始证书到服务器,这时候初始证书是未验证的,然后导出为crt/cer文件(可能拼写错误,总之是正规证书后缀),再导入到机构. 要代理所有类型包括ssl的才能正常导入机构 ...
- jquery 直接访问图片路径
jQuery("#img").attr("src",function(){return this.src+"?"});