一、  实验内容

(一)敏捷开发与XP

摘要:一项实践在XP环境中成功使用的依据通过XP的法则呈现,包括:快速反馈、假设简单性、递增更改、提倡更改、优质工作。XP软件开发的基石是XP的活动,包括:编码、测试、倾听、设计。

学习:XP是一种更加灵活的开发方式和理念,通过迅速的反应及时充分修改程序,保证所有团队成员对资源和责任的共享;适用于“小而精”的团队开发。同时,其所倡导的“倾听”也是实现了程序开发“需求至上”的终极目标。

(二)编码标准

摘要:编程标准包含:具有说明性的名字、清晰的表达式、直截了当的控制流、可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性。

操作:

  1. 格式规范——在eclipse中,用source->Format进行格式规范;
  2. 命名规范——包名全部小写,如: awt ;类名第一个字母要大写,如:HelloWorld;

学习:在团队操作中,格式规范是为提高效率扫清障碍的做法;命名规范则具有很强灵活性,根据各团队不同的情况和习惯进行,不仅是方便自己,更是方便团队其他成员。

(三)结对编程

摘要:结对编程中的角色分配——驾驶员(控制键盘输入),领航人(起到领航、提醒作用)

(四)版本控制

摘要:版本控制提供项目级的 undo(撤销) 功能;•  版本控制允许多人在同一代码上工作;•   版本控制系统保存了过去所作的修改的历史记录;具体步骤如下——

# 添加修改文件

$ git add 所有修改的文件

# 提交到环境中本地代码仓库

$ git commit -m '本次修改的描述'

# push到git.shiyanlou.com,无需输入密码

$ git push

学习:按照要求指导,逐步完成如下——

图1 创建HelloWorld

图2 检验是否跟踪

图3 编译并运行文件

图4 检查是否跟踪

图5 结果

(五)重构

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

学习:尝试Encapsulate Field功能如下——

图6 编写代码

图7 运行结果

清除代码重复的重构方法——同一class中重复,则提炼重复;互为兄弟的模块内重复,则提炼到父类中;不同的方法做同样的事,则选择更清晰的算法而将另外的算法清除;

此外,在重构代码后,还有一个必不可少的步骤即进行新一轮的测试,即产品代码仍要通过之前的所有测试。

(六)实践项目

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相关测试

3.设计思路(20135211,20135216)

首先,根据用户需求合理分配代码密度,即:

  1. 用户直接操作(点击运行)的程序为主控程序,仅包含对与用户接触的窗口的定义语句和相关函数调用;
  2. 后台处理图形化界面的语句组成控制程序,包括:对话框算法、蛇和果实(对象)的位置显示和移动算法、对象位置记录、暂停键及停止条件函数等。

其次,对具体程序进行编写:

  1. MainClass函数:继承JFrame类,调用ControlSnake类;定义窗口大小和位置
  2. ControlSnake函数:继承JPanel类;定义贪吃蛇的坐标位置和果实坐标位置,定义随机数发生器等;建立主函数接收键盘传入并转换成keyCode,执行对应操作;建立Paint函数构造窗口;建立Action函数进行动画演示(包括调用随机数发生函数产生伪随机序列,确定果实位置)

最后,对难点进行攻克:

  1. 如何在蛇碰到边界后产生对话框提示用户重新开始?

参阅资料后,决定在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;

}

}

5.代码测试及思路(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(), );

}

}

6.过程记录(20135211)

1 初始命名有误

2 重命名

3 格式不规范

测试类使用

 

6.时间统计

 

        

步骤

耗时

百分比

需求分析

1.5h

16.7%

设计

3h(包括学习)

33.3%

代码实现

3h(包括学习)

33.3%

测试

1h(包括学习)

11.1%

分析总结

0.5h

5.6%

7.实验感悟

本次实验较为复杂,考察动手能力、查阅资料能力、知识掌握程度等多方面内容。通过团队合作,我们不仅对游戏开发有了更深刻的认识,更对XP这一思想有了初步掌握,并且复习了TDD等内容。

补充:20135211 李行之 博客地址:http://www.cnblogs.com/shadow135211/

Java实验三报告的更多相关文章

  1. 20172301 《Java软件结构与数据结构》实验三报告

    20172301 <Java软件结构与数据结构>实验三报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 郭恺 学号:20172301 实验教师:王志强老师 ...

  2. 20172329 2018-2019 《Java软件结构与数据结构》实验三报告

    20172329 2018-2019-2 <Java软件结构与数据结构>实验三报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 王文彬 学号:2017232 ...

  3. 20172310 2017-2018-2 《程序设计与数据结构》实验三报告(敏捷开发与XP实践)

    20172310 2017-2018-2 <程序设计与数据结构>实验三报告(敏捷开发与XP实践) 课程:<程序设计与数据结构> 班级: 1723 姓名: 仇夏 学号:20172 ...

  4. 20145203盖泽双java实验三 敏捷开发与XP实践

    java实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> ...

  5. 20165324 Java实验三 敏捷开发与XP实验

    20165324 Java实验三 敏捷开发与XP实验 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:何春江 学号:20165324 指导教师:娄嘉鹏 实验日期:2018年4月16日 ...

  6. 20192113 2020-2021-2 《Python程序设计》实验三报告

    20192113 2020-2021-2 <Python程序设计>实验三报告 课程:<Python程序设计> 班级: 1921 姓名: 衣丽莎 学号:20192113 实验教师 ...

  7. 20192204李龙威 2019-2020-2 《Python程序设计》实验三报告

    20192204李龙威 2019-2020-2 <Python程序设计>实验三报告 课程:<Python程序设计> 班级: 1922 姓名: 李龙威 学号:20192204 实 ...

  8. 20145302张薇《Java程序设计》实验三报告

    20145302张薇<Java程序设计>实验三:敏捷开发与XP实践 实验内容 使用git上传代码 使用git实现代码开发实践 实现代码的重载 使用git上传代码 git init git ...

  9. 20172309 《Java软件结构与数据结构》实验三报告

    课程:<程序设计与数据结构(下)> 班级:1723 姓名: 王志伟 学号:20172309 实验教师:王志强老师 实验日期:2018年11月2日 必修/选修: 必修 实验内容: 实验一: ...

随机推荐

  1. BZOJ4182 : Shopping

    最后选择的一定是树上的一个连通块,考虑树分治,每次只需考虑重心必选的情况,这就变成了以重心为根的树形依赖多重背包问题. 设f[x][j]表示从根节点到x这条路径及其左边的所有节点,以及以x为根的子树的 ...

  2. 【BZOJ】1003: [ZJOI2006]物流运输trans(SPFA+DP)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1003 这题一开始看是不会的额,,,还是看题解了..一开始我觉得不能用最短路啥的,,看了题解发现这是d ...

  3. COJ967 WZJ的数据结构(负三十三)

    WZJ的数据结构(负三十三) 难度级别:C: 运行时间限制:7000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大 ...

  4. windows环境下nginx的启动、停止

    Windows下Nginx的启动.停止等命令 在Windows下使用Nginx,我们需要掌握一些基本的操作命令,比如:启动.停止Nginx服务,重新载入Nginx等,下面我就进行一些简单的介绍.1.启 ...

  5. .NET正则基础之——平衡组

    1        概述 平衡组是微软在.NET中提出的一个概念,主要是结合几种正则语法规则,提供对配对出现的嵌套结构的匹配..NET是目前对正则支持最完备.功能最强大的语言平台之一,而平衡组正是其强大 ...

  6. OpenCV2.4.10 Mac Qt Configuration

    Download OpenCV 2.4.10 Download CMake 2.8 Open CMake and choose the source code directory and build ...

  7. java.lang.String 类的所有方法

    java.lang.String 类的所有方法 方法摘要 char charAt(int index) 返回指定索引处的 char 值. int codePointAt(int index) 返回指定 ...

  8. Wilddog - 野狗常用知识点

    https://www.wilddog.com/examples/chat-var1 https://z.wilddog.com/web/quickstart 增加或者修改替换整条数据(注意,upda ...

  9. ASP.NET WEB API的服务托管(Self-HOST)

    如果我们想对外发布RESTful API,可以基于ASP.NET来构建Restful APIs,但需要部署IIS吗?答案是不必.你可以把它托管到一个Windows Service.具体如何把WEB A ...

  10. java类的继承

    继承就是在一个现有类型的基础上,通过增加新的方法或者重定义已有方法(重写)的方式,产生一个新的类型.继承是面向对 象的三个基本特征--封装.继承.多态的其中之一,我们在使用java时编写的每一个类都是 ...