标签:
一、实验内容
(一)敏捷开发与XP
软件开发流程的目的是为了提高软件开发、运营、维护的效率,并提高软件的质量、用户满意度、可靠性和软件的可维护性。 光有各种流程的思想是不够的,我们还要有一系列的工具来保证这些思想能够在实践中有效率地运作。一个常见的公式是:软件工程=开发流程+工具。敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法。“敏捷流程”是一系列价值观和方法论的集合。
其中,极限编程(eXtreme Programming,XP)是 是一种全新而快捷的软件开发方法。XP团队使用现场客户、特殊计划方法和持续测试来提供快速的反馈和全面的交流:
XP是以开发符合客户需要的软件为目标而产生的一种方法论
XP是一种以实践为基础的软件工程过程和思想
XP认为代码质量的重要程度超出人们一般所认为的程度
XP特别适合于小型的有责任心的、自觉自励的团队开发需求不确定或者迅速变化的软件
XP软件开发是什么样的通过 XP准则来表达:
沟通 :XP认为项目成员之间的沟通是项目成功的关键,并把沟通看作项目中间协调与合作的主要推动因素。
简单 :XP假定未来不能可靠地预测,在现在考虑它从经济上是不明智的,所以不应该过多考虑未来的问题而是应该集中力量解决燃眉之急。
反馈 :XP认为系统本身及其代码是报告系统开发进度和状态的可靠依据。系统开发状态的反馈可以作为一种确定系统开发进度和决定系统下一步开发方向的手段。
勇气:代表了XP认为人是软件开发中最重要的一个方面的观点。在一个软件产品的开发中人的参与贯穿其整个生命周期,是人的勇气来排除困境,让团队把局部的最优抛之脑后,达到更重大的目标。表明了XP对“人让项目取得成功”的基本信任态度。
一项实践在XP环境中成功使用的依据通过XP的法则呈现,包括:快速反馈、假设简单性、递增更改、提倡更改、优质工作。
XP软件开发的基石是XP的活动,包括:编码、测试、倾听、设计。
(二)编码标准
编程标准包含:具有说明性的名字、清晰的表达式、直截了当的控制流、可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性。
程序没有最基本的缩进,让人读起来很费劲,这个问题在Eclipse中比较容易解决,我们单击Eclipse菜单中的source->Format 或用快捷键Ctrl+Shift+F就可以按Eclipse规定的规范缩进。
代码标准中很重要的一项是如何给包、类、变量、方法等标识符命名,能很好的命名可以让自己的代码立马上升一个档次。Java中的一般的命名规则有:
方法名第一个字母要小写:setName
(三)结对编程
结对编程是XP中的重要实践。在结对编程模式下,一对程序员肩并肩、平等地、互补地进行开发工作。他们并排坐在一台电脑前,面对同一个显示器,使用同一个键盘、同一个鼠标一起工作。他们一起分析,一起设计,一起写测试用例,一起编码,一起做单元测试,一起做集成测试,一起写文档等。 结对编程中有两个角色:
如何结对编程,为何要结对编程,重点是:
团队精神是好多地方都强调的一个精神,最小的团队就是一对一的二人团队了,培养团队精神从结对编程开始吧。社会生活中人与人相处最重要的是诚信,有同理心,互利。结对编程中大家会出现分歧,如何更有效地合作要做到对事不对人。
(四)版本控制
XP的集体所有制意味着每个人都对所有的代码负责;这一点,反过来又意味着每个人都可以更改代码的任意部分。结对编程对这一实践贡献良多:借由在不同的结对中工作,所有的程序员都能看到完全的代码。集体所有制的一个主要优势是提升了开发程序的速度,因为一旦代码中出现错误,任何程序员都能修正它。 这意味着代码要放到一个大家都能方便获取的地方,我们叫代码仓库。这引出另外一个话题叫版本控制(Version Control)。
不论是对于团队还是个体,版本控制都提供了很多好处。
http://git.shiyanlou.com/Hazel5336/shiyanlou_cs212
(五)重构
我们先看看重构的概念:
重构(Refactor),就是在不改变软件外部行为的基础上,改变软件内部的结构,使其更加易于阅读、易于维护和易于变更 。
重构中一个非常关键的前提就是“不改变软件外部行为”,它保证了我们在重构原有系统的同时,不会为原系统带来新的BUG,以确保重构的安全。如何保证不改变软件外部行为?重构后的代码要能通过单元测试。如何使其更加易于阅读、易于维护和易于变更 ?设计模式给出了重构的目标。
(六)实践项目
一、题目简介
一个简单的扫雷小游戏,在9*9的方格盘上,首先可以设定雷的个数,然后点击开始程序就会随机布雷,开始游戏后如果点到雷就会显示游戏结束,如果没有,会出现数字表示周围一圈雷的个数,以此推理当扫出所有雷将显示游戏胜利。
二、实验结队分工
王维臻:负责代码修改与运行测试部分
张嘉琪:负责代码找寻与编写部分:http://www.cnblogs.com/Juliet5307
三、代码
package
app;
import
view.BoomFrame;
public
class
App {
/**
* @param args
*/
public
static
void
main(String[] args) {
new
BoomFrame();
}
}
package
controller;
import
java.awt.Color;
import
java.awt.event.ActionEvent;
import
java.awt.event.ActionListener;
import
java.io.FileInputStream;
import
javax.swing.JButton;
import
model.ComputeModel;
import
util.FinalFile;
import
view.BoomFrame;
public
class
BoomHandler
implements
ActionListener {
//把整个雷的窗口都传进来
private
BoomFrame win;
private
int
row,col;
public
BoomHandler(BoomFrame win,
int
row,
int
col) {
super
();
this
.win = win;
this
.row=row;
this
.col=col;
}
@Override
public
void
actionPerformed(ActionEvent e) {
setType(row,col);
}
public
void
setType(
int
row,
int
col)
{
JButton but= win.getBut()[row][col];
but.setBorder(FinalFile.DB_LINE);
if
(ComputeModel.isBoomPosi(row, col, win.getBoomoPosi(), win.getBwidth()))
{
but.setBackground(Color.RED);
//踩到雷了
but.setIcon(FinalFile.BOOM_ICO[
0
]);
for
(
int
i =
0
; i < win.getBheight(); i++) {
for
(
int
j =
0
; j < win.getBwidth(); j++) {
if
(ComputeModel.isBoomPosi(i,j, win.getBoomoPosi(), win.getBwidth()))
{
if
(win.getBut()[i][j]==but)
{
continue
;
}
if
(win.getBut()[i][j].getIcon()==FinalFile.FLAG_ICO)
{
win.getBut()[i][j].setIcon(FinalFile.BOOM_ICO[
1
]);
continue
;
}
JButton butTemp=win.getBut()[i][j];
butTemp.setIcon(FinalFile.BOOM_ICO[
2
]);
}
}
}
}
else
{
int
count=ComputeModel.getBoundsBoomCount(row, col, win.getBoomoPosi(), win.getBwidth(), win.getHeight());
if
(count>
0
){
but.setText(count+
""
);
}
else
{
int
[][] bounds=ComputeModel.getBoundsPosi(row, col);
for
(
int
i =
0
; i < bounds.length; i++) {
//检测坐标是否和法
if
(ComputeModel.isPosiOK(bounds[i][
0
], bounds[i][
1
], win.getBwidth(), win.getBheight()))
{
//检测是否坐标所在按钮已被遍历过,如果没有,再进行递归调用
if
(win.getBut()[bounds[i][
0
]][bounds[i][
1
]].getBorder()!=FinalFile.DB_LINE)
{
setType(bounds[i][
0
], bounds[i][
1
]);
}
}
}
}
}
}
}
package
controller;
import
java.awt.event.MouseAdapter;
import
java.awt.event.MouseEvent;
import
java.io.FileInputStream;
import
javax.swing.JButton;
import
model.ComputeModel;
import
util.FinalFile;
import
view.BoomFrame;
public
class
RightHandler
extends
MouseAdapter {
private
BoomFrame win;
public
RightHandler(BoomFrame win) {
super
();
this
.win = win;
}
@Override
public
void
mouseReleased(MouseEvent e) {
super
.mouseReleased(e);
if
(e.isPopupTrigger())
//是否是右键
{
JButton but=(JButton)e.getSource();
if
(but.getIcon()==
null
)
{
but.setIcon(FinalFile.FLAG_ICO);
this
.win.getJtf1().setText(ComputeModel.formatNum((Integer.parseInt(
this
.win.getJtf1().getText())-
1
)));
}
else
if
(but.getIcon()==FinalFile.FLAG_ICO)
{
but.setIcon(FinalFile.QUE_ICO);
this
.win.getJtf1().setText(ComputeModel.formatNum((Integer.parseInt(
this
.win.getJtf1().getText())+
1
)));
}
else
if
(but.getIcon()==FinalFile.QUE_ICO)
{
but.setIcon(
null
);
}
}
}
}
package
model;
import
java.text.DecimalFormat;
import
javax.swing.JButton;
import
controller.BoomHandler;
import
util.FinalFile;
public
class
ComputeModel {
//计算窗口大小
public
static
int
[] getWindowSize(
int
bWidth,
int
bHeight)
{
int
w=FinalFile.BOOM_WIDTH*bWidth+
10
+
8
;
int
h=FinalFile.BOOM_WIDTH*bHeight+
10
+
8
+FinalFile.BOOM_WIDTH*
2
+
5
+
30
;
return
new
int
[]{w,h};
}
//随机给定雷的位置
public
static
int
[] getRandomBoomPos(
int
bWidth,
int
bHeight,
int
boomNum)
{
int
[] posi=
new
int
[boomNum];
int
maxPosi=bHeight*bWidth;
posi[
0
]=(
int
)(Math.random()*maxPosi)+
1
;
for
(
int
i =
0
; i < posi.length;) {
int
temp=(
int
)(Math.random()*maxPosi)+
1
;
boolean
flag=
true
;
for
(
int
j =
0
; j < posi.length; j++) {
if
(temp==posi[j])
{
flag=
false
;
break
;
}
}
if
(flag)
{
posi[i]=temp;
i++;
}
}
return
posi;
}
//计算位置
public
static
int
getPosi(
int
row,
int
col,
int
bWidth)
//bWidth为一行有几个按钮
{
return
row*bWidth+col+
1
;
}
//判断是否雷的位置
public
static
boolean
isBoomPosi(
int
row,
int
col,
int
[] boomPosi,
int
bWidth)
{
int
posi=getPosi(row, col,bWidth);
for
(
int
i =
0
; i < boomPosi.length; i++) {
if
(boomPosi[i]==posi)
{
return
true
;
}
}
return
false
;
}
//计算周围雷的个数
public
static
int
getBoundsBoomCount(
int
rows,
int
cols,
int
[] boomPosi,
int
bWdith,
int
bHeight)
{
int
count=
0
;
//拿到周围格子坐标
int
[][] bounds=getBoundsPosi(rows, cols);
for
(
int
i =
0
; i < bounds.length; i++) {
if
(isPosiOK(bounds[i][
0
], bounds[i][
1
], bWdith, bHeight))
//判断格子是否超界
{
if
(isBoomPosi(bounds[i][
0
], bounds[i][
1
], boomPosi, bWdith))
{
count++;
}
}
}
return
count;
}
//判断指定格子坐标是否合法
public
static
boolean
isPosiOK(
int
row,
int
col,
int
bWidth,
int
bHeight)
{
if
(row<
0
||row>=bWidth)
{
return
false
;
}
if
(col<
0
||col>=bHeight)
{
return
false
;
}
return
true
;
}
//计算周围格子坐标
public
static
int
[][] getBoundsPosi(
int
row,
int
col)
{
int
[][] bounds={
{row-
1
,col-
1
},
{row-
1
,col},
{row-
1
,col+
1
},
{row,col+
1
},
{row+
1
,col+
1
},
{row+
1
,col},
{row+
1
,col-
1
},
{row,col-
1
}
};
return
bounds;
}
//格式化三位数
public
static
String formatNum(
int
num)
{
DecimalFormat df=
new
DecimalFormat(
"000"
);
return
df.format(num);
}
}
package
util;
import
java.awt.BorderLayout;
import
java.awt.Color;
import
javax.swing.BorderFactory;
import
javax.swing.Icon;
import
javax.swing.ImageIcon;
import
javax.swing.border.Border;
import
javax.swing.border.LineBorder;
public
interface
FinalFile {
//等级设定
//初级
int
LEVEL_0_WIDTH=
9
;
int
LEVEL_0_HEIGHT=
9
;
int
LEVEL_0_BOOM=
10
;
//中级
int
LEVEL_1_WIDTH=
16
;
int
LEVEL_1_HEIGHT=
16
;
int
LEVEL_1_BOOM=
40
;
//高级
int
LEVEL_2_WIDTH=
30
;
int
LEVEL_2_HEIGHT=
16
;
int
LEVEL_2_BOOM=
99
;
//定义雷的宽度
int
BOOM_WIDTH=
20
;
//定义边线
Border DB_0=BorderFactory.createBevelBorder(
0
);
//凸起边线
Border DB_1=BorderFactory.createBevelBorder(
1
);
//下凹边线
Border DB_LINE=
new
LineBorder(Color.GRAY);
//单线边线
//图标
Icon START_ICO=
new
ImageIcon(
"image/start.jpg"
);
Icon FLAG_ICO=
new
ImageIcon(
"image/flag.jpg"
);
Icon QUE_ICO=
new
ImageIcon(
"image/question.jpg"
);
Icon[] BOOM_ICO={
new
ImageIcon(
"image/die_boom.jpg"
),
new
ImageIcon(
"image/fake_boom.jpg"
),
new
ImageIcon(
"image/real_boom.jpg"
)
};
}
package
view;
import
java.awt.Color;
import
java.awt.FlowLayout;
import
java.awt.GridLayout;
import
javax.swing.JButton;
import
javax.swing.JFrame;
import
javax.swing.JPanel;
import
javax.swing.JTextField;
import
controller.BoomHandler;
import
controller.RightHandler;
import
model.ComputeModel;
import
util.FinalFile;
public
class
BoomFrame
extends
JFrame {
private
JButton but[][],start;
private
JPanel butPane,typePane;
private
JTextField jtf1,jtf2;
private
int
boomNum,bwidth,bheight;
int
[] boomoPosi;
public
BoomFrame()
{
super
(
"扫雷--初级"
);
boomNum=FinalFile.LEVEL_0_BOOM;
bwidth=FinalFile.LEVEL_0_WIDTH;
bheight=FinalFile.LEVEL_0_HEIGHT;
//给定雷的位置
this
.boomoPosi=ComputeModel.getRandomBoomPos(bwidth, bheight, boomNum);
int
[] size=ComputeModel.getWindowSize(bwidth, bheight);
this
.setBounds(
200
,
200
,size[
0
],size[
1
]);
this
.setLayout(
null
);
this
.typePane=
new
JPanel(
new
FlowLayout(FlowLayout.CENTER,
20
,
2
));
this
.typePane.setBounds(
5
,
5
, size[
0
]-
8
-
10
,FinalFile.BOOM_WIDTH*
2
-
10
);
this
.add(typePane);
this
.typePane.setBorder(FinalFile.DB_1);
jtf1=
new
JTextField(
"0"
+boomNum+
""
);
typePane.add(jtf1);
start=
new
JButton(FinalFile.START_ICO);
start.setBorder(FinalFile.DB_0);
typePane.add(start);
jtf2=
new
JTextField(
"000"
);
typePane.add(jtf2);
//雷面板
butPane=
new
JPanel(
new
GridLayout(
this
.bwidth,
this
.bheight));
butPane.setBounds(
5
,
10
+FinalFile.BOOM_WIDTH*
2
-
10
, FinalFile.BOOM_WIDTH*
this
.bwidth+
4
, FinalFile.BOOM_WIDTH*
this
.bheight+
4
);
butPane.setBorder(FinalFile.DB_1);
RightHandler rth=
new
RightHandler(
this
);
//放按钮进来
but=
new
JButton[
this
.bheight][
this
.bwidth];
for
(
int
i =
0
; i < but.length; i++) {
for
(
int
j =
0
; j < but[i].length; j++) {
but[i][j]=
new
JButton();
butPane.add(but[i][j]);
but[i][j].setBorder(FinalFile.DB_0);
but[i][j].setBackground(Color.LIGHT_GRAY);
but[i][j].addActionListener(
new
BoomHandler(
this
, i, j));
but[i][j].addMouseListener(rth);
}
}
this
.add(butPane);
this
.setVisible(
true
);
this
.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public
static
void
main(String[] args) {
}
public
JButton[][] getBut() {
return
but;
}
public
void
setBut(JButton[][] but) {
this
.but = but;
}
public
JButton getStart() {
return
start;
}
public
void
setStart(JButton start) {
this
.start = start;
}
public
JPanel getButPane() {
return
butPane;
}
public
void
setButPane(JPanel butPane) {
this
.butPane = butPane;
}
public
JPanel getTypePane() {
return
typePane;
}
public
void
setTypePane(JPanel typePane) {
this
.typePane = typePane;
}
public
JTextField getJtf1() {
return
jtf1;
}
public
void
setJtf1(JTextField jtf1) {
this
.jtf1 = jtf1;
}
public
JTextField getJtf2() {
return
jtf2;
}
public
void
setJtf2(JTextField jtf2) {
this
.jtf2 = jtf2;
}
public
int
getBoomNum() {
return
boomNum;
}
public
void
setBoomNum(
int
boomNum) {
this
.boomNum = boomNum;
}
public
int
getBwidth() {
return
bwidth;
}
public
void
setBwidth(
int
bwidth) {
this
.bwidth = bwidth;
}
public
int
getBheight() {
return
bheight;
}
public
void
setBheight(
int
bheight) {
this
.bheight = bheight;
}
public
int
[] getBoomoPosi() {
return
boomoPosi;
}
public
void
setBoomoPosi(
int
[] boomoPosi) {
this
.boomoPosi = boomoPosi;
}
}
(七)总结
通过结对项目,我认识到了合作的重要性,紧密的合作能够提高我们的能力。代码测试过程中出现很多错误,但经过互相的合作和探讨,加以改进,便可以成功运行。
标签:
原文地址:http://www.cnblogs.com/20135336wwz/p/4553524.html