实验三 敏捷开发与XP实现

实验内容

  1. XP基础

  2. XP核心实践

  3. 相关工具

实验要求

  1. 了解敏捷开发的基本方法以及XP软件开发的相关准则;了解代码编写的标准和原则;体会结对编程的好处;

  2. 实践体会版本控制的方法及优势;

  3. 利用重构完善代码;

  4. 通过结对方式编写软件;

实验步骤

(一)敏捷开发与XP

敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法

软件工程=开发流程+工具 软件=程序+软件工程 软件企业=软件+商业模式

极限编程(eXtreme Programming,XP)是是一种全新而快捷的软件开发方法

•XP是以开发符合客户需要的软件为目标而产生的一种方法论;

•XP是一种以实践为基础的软件工程过程和思想;

•XP认为代码质量的重要程度超出人们一般所认为的程度;

•XP特别适合于小型的有责任心的、自觉自励的团队开发需求不确定或者迅速变化的软件;

XP的法则:快速反馈、假设简单性、递增更改、提倡更改、优质工作;

XP的活动:编码、测试、倾听、设计;

XP实践:项目成员用户成功执行XP活动的技术通过XP实践来呈现;

(二)编码标准

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

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

要体现各自的含义

包、类、变量用名词

方法名用动宾

包名全部小写,如:io,awt

类名第一个字母要大写,如:HelloWorldApp

变量名第一个字母要小写,如:userName

方法名第一个字母要小写:setName

目前IDEA中已经能自动修改缩进格式如图:

(三)结对编程

结对编程是XP中的重要实践

•在合作中进行程序开发,在两种角色之间相互转换,培养团队精神。

(四)版本控制

•版本控制的好处:

  1. 版本控制提供项目级的 undo(撤销) 功能:这意味着你的项目不会因为操作失误而丢失;

  2. 版本控制允许多人在同一代码上工作, 只要遵守一定的控制原则就行:不会因代码覆盖而导致前人修改代码无效;

  3. 版本控制系统保存了过去所作的修改的历史记录:可以知道谁修改了代码,查出原因;

版本控制系统还支持在主线上开发的同时发布多个软件版本:不必在软件发布时停下或冻结代码;

  1. 版本控制也是项目级的时间机器,你可以选择任何一个时间, 精确地查看项目在当时的情况:是重现以前某个有问题的发布版本的基础;

•流行的版本控制工具有CVS,SVN,Git等;

•使用Git进行版本控制的实践(包括结对编程中代码的提交与下载)

不下载安装git到本地就只能使用最没有效率的复制粘贴。

按照代码托管步骤进行:

  1. 下载安装gitAPP到本地,打开命令行模式,输入git指令,即可使用,如图:

  1. 命令行模式下给git配置自己的用户名和邮箱,如图:

  1. 配置ssh公钥步骤,如图:

配置成功:

  1. 写好需要上传的项目:即Hello.java

  2. 准备工作完成,开始托管代码:

与git@osc建立连接:

找到需要上传项目的位置并Git Bush Here一下,在命令窗口中第二次建立连接(不再需要输入用户名和密码):

输入相应指令如图:

git init git add git add. git commit git commit -m

push失败

在IDEA中配置并使用git更加方便快捷,如图:

push成功并与结对伙伴相互尝试下载:

(五)重构

重构(Refactor),就是在不改变软件外部行为的基础上,改变软件内部的结构,使其更加易于阅读、易于维护和易于变更 。

•对重构功能的应用与实践

重命名

代码的封装

解决代码重复

•重构的好处(软件的修改与维护)

增加新功能;

原有功能有BUG;

改善原有程序的结构;

优化原有系统的性能 。

•哪些地方需要重构

最不能出现的就是代码的重复 Duplicated Code

最单纯的Duplicated Code就是[同一个class内的两个方法含有相同表达式(expression)]。这时候你需要做的就是采用Extract Method提炼出重复的代码,然后让这两个地点都调用被提炼出来的那一段代码。

另一种常见情况就是[两个互为兄弟(sibling)的subclasses内含有相同表达式]。要避免这种情况,只需要对两个classes都使用Extract Method,然后再对被提炼出的代码使用Pull Up Method,将它推入superclass内。

如果代码之间只是类似,并非完全相同,那么就得运用Extract Method将相似部分和差异部分割开,构成单独一个方法。然后你可能发现或许可以运用Form Template Method获得一个Template Method设计模式。

如果有些方法以不同的算法做相同的事,你可以择定其中较清晰的一个,并使用Substitute Algorithm将其它方法的算法替换掉。

如果两个毫不相关的classes内出现Duplicaded Code,你应该考虑对其中一个使用Extract Class,将重复代码提炼到一个独立class中,然后在另一个class内使用这个新class。但是,重复代码所在的方法也可能的确只应该属于某个class,另一个class只能调用它,抑或这个方法可能属于第三个class,而另两个classes应该引用这第三个class。你必须决定这个方法放在哪儿最合适,并确保它被安置后就不会再在其它任何地方出现。

•其他Bad Smell与相应的重构手法如下表所示:

(六)实践项目

结对伙伴网址:https://home.cnblogs.com/u/20145210ysy/

贡献均等,重构过程、TDD等,抱歉两天的时间内实在无法完成能力有限。

代码如下:

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();
control.setFocusable(true);
kit = Toolkit.getDefaultToolkit();
dimen = kit.getScreenSize(); add(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;
}
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 {
Random rand; ArrayList<Point> list, listBody; 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>();
listBody = new ArrayList<Point>(); x = 5;
y = 5;
list.add(new Point(x, y));
listBody.add(list.get(0)); dx = 10;
dy = 0; fx = rand.nextInt(30) * 10 + 5;// 2
fy = rand.nextInt(30) * 10 + 5;// 2 setBackground(Color.WHITE);
setSize(new Dimension(318, 380)); final Timer time = new Timer(speed, this);
time.start(); addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 37) {
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) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, 400, 400);
g.setColor(Color.DARK_GRAY);
g.drawLine(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++) {
g.fillRect(listBody.get(i).x, listBody.get(i).y, 9, 9);
}
g.fillRect(x, y, 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;
}
}

运行结果如图:

遇到的问题及解决方法

使用cmd命令行一开始托管代码失败了,经过在IDEA中设置的最后一步输入账号和密码时,发现修改过用户名,所以在更正了用户名后托管成功。

在实践项目中设计思路有一定问题,大体参照了前面同学的成果并尝试理解、改进。

比起用git add、git commit、git push的节奏托管代码,我现在还是比较倾向于简单的复制粘贴,可能是刚开始还不太适应,希望以后熟悉了它能真正带来便利。

Personal Software Process Time

步骤 耗时 百分比
需求分析 3hour 9.8%
设计代码实现 10hours 82%
测试 2hours 6.6%
分析总结 0.5hour 1.6%

20145231《Java程序设计》第三次实验报告的更多相关文章

  1. 20145330《Java程序设计》第二次实验报告

    20145330<Java程序设计>第二次实验报告 实验二 Java面向对象程序设计 实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承多态 3.初步掌握UM ...

  2. 20145320《Java程序设计》第二次实验报告

    20145320<Java程序设计>第二次实验报告 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1453 指导教师:娄嘉鹏 实验日期:2016.04.12 15: ...

  3. 《Java程序设计》第二次实验报告

    20145220 <Java程序设计>第二次实验报告 课程:Java程序设计 指导教师:娄嘉鹏 实验日期:2016.04.12 实验名称:Java面向对象程序设计 实验内容 初步掌握单元测 ...

  4. 20145333 《Java程序设计》第二次实验报告

    2014333 <Java程序设计>第二次实验报告 课程:Java程序设计 指导教师:娄嘉鹏 实验日期:2016.04.12 实验名称:Java面向对象程序设计 实验内容 初步掌握单元测试 ...

  5. 20145240 《Java程序设计》第二次实验报告

    20145240 <Java程序设计>第二次实验报告 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.04.12 实验 ...

  6. Java程序设计第四次实验报告

    北京电子科技学院(BESTI) 实     验    报     告 课程:java程序设计 班级:1352  姓名:何伟钦  学号:20135223 成绩:            指导教师:娄嘉鹏 ...

  7. 20145231《Java程序设计》第二次实验报告

    实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD: 理解并掌握面向对象三要素: 初步掌握UML建模: 熟悉S.O.L.I.D原则: 了解设计模式: 实验要求 实现并体会例子中代码的 ...

  8. 20145216史婧瑶《Java程序设计》第二次实验报告

    实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计 ...

  9. 201521123008<java程序设计>第三周实验总结

    1.本周学习总结 2.书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; pub ...

  10. 20145320《Java程序设计》第三次实验报告

    20145320<Java程序设计>第三次实验报告 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1453 指导教师:娄嘉鹏 实验日期:2016.04.22 15: ...

随机推荐

  1. Chromium浏览器组件设计意图

    在文章開始之前.我要叽歪几句,一上来就看Chrome的代码.简直晕头转向,摸来摸去莫不着头脑,好不easy看了一点点代码.却犹如瞎子摸象.无法众观全局.以下这篇小文,简介当中一个重要的模块--Comp ...

  2. spark通过合理设置spark.default.parallelism参数提高执行效率

    spark中有partition的概念(和slice是同一个概念,在spark1.2中官网已经做出了说明),一般每个partition对应一个task.在我的测试过程中,如果没有设置spark.def ...

  3. POI Excel 冷冻线

    冷冻线 Sheet.createFreezePane data bar and  color scale SheetConditionalFormatting scf = sheet.getSheet ...

  4. 抒发一下这些天用django做web项目的一些体会

    最近接触了一段时间的python,觉得python写脚本还是挺方便的,做一个简单的桌面应用也很nice,但是随着深入,对python做功能复杂的web项目我彻底死心了​,每个环节都是一堆的坑,部署阶段 ...

  5. Android-ViewPagerIndicator框架使用——LinePageIndicator

    前言:LinePageIndicator类似CirclePageIndicator,只是将圆点指示变成了长条指示. 一:使用是定义的布局文件simple_lines : <LinearLayou ...

  6. Apache thrift - 使用,内部实现及构建一个可扩展的RPC框架

    本文首先介绍了什么是Apache Thrift,接着介绍了Thrift的安装部署及如何利用Thrift来实现一个简单的RPC应用,并简单的探究了一下Thrift的内部实现原理,最后给出一个基于Thri ...

  7. Xamarin.Forms学习之Page Navigation(二)

    在上一篇的文章中,对页面常规的导航做一些分享,然而在实际的编程中,页面数据的保持,传值等等都有很多,这篇文章就对这些相关内容做一个分享和记录,有问题,希望大家留言指正.这一篇从实现业务逻辑来讲并没有什 ...

  8. 20160924-2——mysql常见问题集锦

    一.数据类型相关问题 1.varchar(N)占用多少空间 (1)varchar(N)里的N是字符数,而不是字节数: (2)字符类型(varchar text blob等)空间=字符实际长度+字段长度 ...

  9. IOS开发复习笔记(1)-OC基础知识

    在上班之余学习IOS已经有三个多月了,因为基础有些薄弱从OC的基本语法开始学习的,相继看了青柚子和红柚子的书,现在在看编程实战,趁这个机会好好的总结一下: 1.命名约定 对象类型和名称一致,以免混淆 ...

  10. 洛谷 P1407 [国家集训队]稳定婚姻

    洛谷 这个题面很有意思,像我这样的菜鸡,完全不需考虑婚姻的稳定 性 问题. tarjan裸题,直接讲算法吧: 原配夫妻之间分别连一条边,小情人之间反向连边. 这时候我们会发现一个性质,如果婚姻稳定,那 ...