實驗三 敏捷開發與Xp實踐

北京電子科技學院java

實      驗      報      告git

課程:移動平臺應用開發實踐  班級:201592  姓名:楊鳳  學號:20159213程序員

成績:___________  指導老師:婁嘉鵬   實驗日期 :2015.10.17算法

實驗名稱:                          Java敏捷開發與XP實踐                                         編程

實驗內容:                      一、XP基礎      二、XP核心實踐    三、相關工具               設計模式

 

 

實驗步驟安全

(一)敏捷開發與XPdom

1.敏捷開發(Agile Development)是一種以人爲核心、迭代、按部就班的開發方法。工具

2.常見的開發流程有:單元測試

  • RUP(Rational Unified Process)
  • PSP(Personal Software Process )
  • TSP(Team Software Process )
  • Agile Process

3.XP軟件開發的準則:

  • 溝通 :XP認爲項目成員之間的溝通是項目成功的關鍵,並把溝通看做項目中間協調與合做的主要推進因素。
  • 簡單 :XP假定將來不能可靠地預測,在如今考慮它從經濟上是不明智的,因此不該該過多考慮將來的問題而是應該集中力量解決燃眉之急。
  • 反饋 :XP認爲系統自己及其代碼是報告系統開發進度和狀態的可靠依據。系統開發狀態的反饋能夠做爲一種肯定系統開發進度和決定系統下一步開發方向的手段。
  • 勇氣:表明了XP認爲人是軟件開發中最重要的一個方面的觀點。在一個軟件產品的開發中人的參與貫穿其整個生命週期,是人的勇氣來排除困境,讓團隊把局部的最優拋之腦後,達到更重大的目標。代表了XP對「人讓項目取得成功」的基本信任態度。

4.XP軟件開發的基石是XP的活動包括:編碼、測試、傾聽、設計。

(二)編碼標準

      編寫代碼一個重要的認識是「程序大多時候是給人看的」,編程標準使代碼更容易閱讀和理解,甚至能夠保證其中的錯誤更少。編程標準包含:具備說明性的名字、清晰的表達式、直截了當的控制流、可讀的代碼和註釋,以及在追求這些內容時一致地使用某些規則和慣用法的重要性。編碼標準中的版式就是一個很好的例子,版式雖然不會影響程序的功能,但會影響可讀性。程序的版式追求清晰、美觀,是程序風格的重要因素。

咱們看程序沒有縮進的例子:

這個編碼讓人讀起來比較費勁,這個問題在Eclipse經過菜單中的source->Format或者快捷鍵Ctrl+Shit+F就能讓程序自動縮進。

這兩張圖進行比較,第二張是否是更有可讀性,看起來更清晰。因此編程要注意程序結構的可讀性。

(三)結對編程

結對編程兩我的的角色和做用:

  • 駕駛員(Driver)是控制鍵盤輸入的人。
  • 領航員(Navigator)起到領航、提醒的做用。

如何結對編程,爲什麼要結對編程:

  • 駕駛員:寫設計文檔,進行編碼和單元測試等XP開發流程。
  • 領航員:審閱駕駛員的文檔、駕駛員對編碼等開發流程的執行;考慮單元測試的覆蓋率;思考是否須要和如何重構;幫助駕駛員解決具體的技術問題。
  • 駕駛員和領航員不斷輪換角色,不要連續工做超過一小時,每工做一小時休息15分鐘。領航員要控制時間。
  • 主動參與。任何一個任務都首先是兩我的的責任,也是全部人的責任。沒有「個人代碼」、「你的代碼」或「他/她的代碼」,只有「咱們的代碼」。
  • 只有水平上的差距,沒有級別上的差別。兩人結對,儘管可能你們的級別資歷不一樣,但無論在分析、設計或編碼上,雙方都擁有平等的決策權利。

(四)版本控制

XP在結對編程中有不少優點,若是一旦代碼有問題,任何程序員都能修正它。這意味着代碼要放到一個你們都能方便取得的地方,咱們稱爲代碼庫。咱們就能引出另外一個話題:版本控制。如下是實驗的過程:

咱們給一個HelloWorld的例子,首先進入實驗樓Code目錄創建一個shiyanlou_cs212目錄並建立HelloWorld目錄和編輯HelloWOrld.java。以下圖

在上一部沒有問題下,咱們能夠提交

編好的程序必須提交保存,操做以下:

咱們也能夠修改,咱們修改並運行以下

(五)重構

重構(Refactor),就是在不改變軟件外部行爲的基礎上,改變軟件內部的結構,使其更加易於閱讀、易於維護和易於變動 。重構中一個很是關鍵的前提就是「不改變軟件外部行爲」,它保證了咱們在重構原有系統的同時,不會爲原系統帶來新的BUG,以確保重構的安全。如何保證不改變軟件外部行爲?重構後的代碼要能經過單元測試。如何使其更加易於閱讀、易於維護和易於變動 ?設計模式給出了重構的目標。

在Eclipse 中Rename ,能夠給類、包、方法、變量更名字。以ABC爲例

這個類,類名,方法名和方法的參數名都有問題,沒有註釋的話是沒法理解代碼的。咱們可使用Eclipse中的重構功能來更名。修改方法是,用鼠標單擊要改的名字,選擇Eclipse中菜單中的Refactor->Rename:

學過C語言的學生學Java時常犯的毛病是不會封裝,該用類的地方都用告終構體。好比要定義一個類Student,會出現這樣的代碼:

Eclipse中菜單中的Refactor->Encapsulate Field

 

因爲Java中全部的類都有個專門的toString方法,咱們使用Eclipse中Source->Generate
toString()... 給Student類產生一個toString方法,以下圖:

通過main的修改運行結果以下所示:

 

(六)實踐項目

咱們組作的實驗是掃雷;代碼以下:

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Container;

import java.awt.GridLayout;

import java.awt.Label;

import java.awt.Panel;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

import javax.swing.Icon;

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JOptionPane;

import javax.swing.JTextField;

import javax.swing.SwingUtilities;

class Bomb extends JButton {

private static final long serialVersionUID = 1L;

public int num_x, num_y; // 第幾號方塊

public int BombRoundCount; // 周圍雷數

public boolean isBomb; // 是否爲雷

public boolean isClicked; // 是否被點擊

public int BombFlag; // 探雷標記

public boolean isRight; // 是否點擊右鍵

public Bomb(int x, int y) {

BombFlag = 0;

num_x = x;

num_y = y;

BombRoundCount = 0;

isBomb = false;

isClicked = false;

isRight = false;

}

}

 

/* 窗口及算法實現類 */

class MainBomb extends JFrame implements ActionListener, MouseListener {

private static final long serialVersionUID = 1L;

public JTextField text;

public Label nowBomb, setBomb;

public int BlockNum, BombNum; // 當前方塊數當前雷數

public Icon icon_bomb = new ImageIcon("Bomb.gif"); // 踩雷

public Icon icon_bomb_big = new ImageIcon("bomb_big.gif"); // 踩雷標記

public Icon icon_flag = new ImageIcon("flag.gif"); // 雷標記

public Icon icon_question = new ImageIcon("question.gif"); // 疑惑是否有雷

public JButton start = new JButton(" 開始 ");

public Panel MenuPamel = new Panel();

public Panel mainPanel = new Panel();

public Bomb[][] bombButton;

 

/* 界面設計 */

public MainBomb() {

super("掃雷   楊鳳孫楠 ");

BlockNum = 64;

BombNum = 10;

Container c = getContentPane();

c.setBackground(Color.gray);

c.setLayout(new BorderLayout());

text = new JTextField("10 ", 3);

nowBomb = new Label("當前雷數" + " " + BombNum + "");

setBomb = new Label("設置地雷數");

start.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

BombNum = Integer.parseInt(text.getText().trim());

if (BombNum >= 10 && BombNum < 50)

replay();

else {

new JOptionPane();

JOptionPane.showMessageDialog(null, "你設置的地雷數太多了,請重設!",

"錯誤", 2);

}

}

});

MenuPamel.add(setBomb);

MenuPamel.add(text);

MenuPamel.add(start);

MenuPamel.add(nowBomb);

c.add(MenuPamel, "North");

mainPanel.setLayout(new GridLayout((int) Math.sqrt(BlockNum),

(int) Math.sqrt(BlockNum)));

bombButton = new Bomb[(int) Math.sqrt(BlockNum)][];

for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {

bombButton[i] = new Bomb[(int) Math.sqrt(BlockNum)];

}

for (int i = 0; i < (int) Math.sqrt(BlockNum); i++)

for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {

bombButton[i][j] = new Bomb(i, j);

bombButton[i][j].setForeground(Color.gray);

bombButton[i][j].addActionListener(this);

bombButton[i][j].addMouseListener(this);

}

for (int i = 0; i < (int) Math.sqrt(BlockNum); i++)

for (int j = 0; j < (int) Math.sqrt(BlockNum); j++)

mainPanel.add(bombButton[i][j]);

c.add(mainPanel, "Center");

startBomb();

setSize(400, 400);

setLocation(350, 200);

setResizable(false);

}

 

/* 佈雷 * 

public void startBomb() {

for (int i = 0; i < BombNum; i++) {

int x = (int) (Math.random() * (int) (Math.sqrt(BlockNum) - 1));

int y = (int) (Math.random() * (int) (Math.sqrt(BlockNum) - 1));

if (bombButton[x][y].isBomb == true)

i--;

else

bombButton[x][y].isBomb = true;

}

}

 

/* 從新開始 *

public void replay() {

nowBomb.setText("當前雷數" + " " + BombNum + "");

for (int i = 0; i < (int) Math.sqrt(BlockNum); i++)

for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {

bombButton[i][j].isBomb = false;

bombButton[i][j].isClicked = false;

bombButton[i][j].setEnabled(true);

bombButton[i][j].setText("");

bombButton[i][j].setIcon(null);

}

startBomb();

}

public void isWin() {

int findBomb = 0; // 找到的地雷數

for (int i = 0; i < (int) Math.sqrt(BlockNum); i++)

for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {

if (bombButton[i][j].isBomb == true

&& bombButton[i][j].isRight == true)

findBomb++;

}

if (findBomb == Integer.parseInt(text.getText().trim())) {

new JOptionPane();

JOptionPane.showMessageDialog(this, "你挖完了全部的雷,你勝利了!", "你勝利了", 2);

}

}

public void CountRoundBomb() {

for (int i = 0; i < (int) Math.sqrt(BlockNum); i++) {

for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {

int count = 0;

// 當須要檢測的單元格自己無地雷的狀況下,統計周圍的地雷個數

if (bombButton[i][j].isBomb != true) {

if ((i - 1 >= 0) && (j - 1 >= 0)) {

if (bombButton[i - 1][j - 1].isBomb == true) {

count += 1; // 檢測左上方空格是不是地雷

}

}

if ((i - 1 >= 0)) {

if (bombButton[i - 1][j].isBomb == true) {

count += 1; // 檢測上方空格是否爲地雷

}

}

if ((i - 1 >= 0)

&& (j + 1 <= (int) Math.sqrt(BlockNum) - 1)) {

if (bombButton[i - 1][j + 1].isBomb == true) {

count += 1; // 檢測右上方是否爲地雷

}

}

if ((j - 1 >= 0)) {

if (bombButton[i][j - 1].isBomb == true) {

count += 1; // 檢測左邊是否爲地雷

}

}

if ((i >= 0) && (j + 1 <= (int) Math.sqrt(BlockNum) - 1)) {

if (bombButton[i][j + 1].isBomb == true) {

count += 1; // 右邊

}

}

if ((j - 1 >= 0)

&& (i + 1 <= (int) Math.sqrt(BlockNum) - 1)) {

if (bombButton[i + 1][j - 1].isBomb == true) {

count += 1; // 左下

}

}

if ((i + 1 <= (int) Math.sqrt(BlockNum) - 1)) {

if (bombButton[i + 1][j].isBomb == true) {

count += 1; // 

}

}

if ((j + 1 <= (int) Math.sqrt(BlockNum) - 1)

&& (i + 1 <= Math.sqrt(BlockNum) - 1)) {

if (bombButton[i + 1][j + 1].isBomb == true) {

count += 1; // 右下

}

}

bombButton[i][j].BombRoundCount = count;

}

}

}

/** 當選中的位置爲空,則翻開周圍的地圖 **/

public void isNull(Bomb[][] bombButton, Bomb ClickecButton) {

int i, j;

i = ClickecButton.num_x;

j = ClickecButton.num_y;

if (ClickecButton.isBomb == true) {

} else {

if ((i - 1 >= 0) && (j - 1 >= 0)) { // 檢測左上方空格是不是空

if (bombButton[i - 1][j - 1].isBomb == false

&& bombButton[i - 1][j - 1].isClicked == false

&& bombButton[i - 1][j - 1].isRight == false) {

bombButton[i - 1][j - 1]

.setText((bombButton[i - 1][j - 1].BombRoundCount)

+ "");

bombButton[i - 1][j - 1].setEnabled(false);

bombButton[i - 1][j - 1].isClicked = true;

}

}

if ((i - 1 >= 0)) { // 檢測上方空格是否爲空

if (bombButton[i - 1][j].isBomb == false

&& bombButton[i - 1][j].isClicked == false

&& bombButton[i - 1][j].isRight == false) {

bombButton[i - 1][j]

.setText((bombButton[i - 1][j].BombRoundCount) + "");

bombButton[i - 1][j].setEnabled(false);

bombButton[i - 1][j].isClicked = true;

}

}

if ((i - 1 >= 0) && (j + 1 <= ((int) Math.sqrt(BlockNum) - 1))) { // 檢測右上方是否爲空

if (bombButton[i - 1][j + 1].isBomb == false

&& bombButton[i - 1][j + 1].isClicked == false

&& bombButton[i - 1][j + 1].isRight == false) {

bombButton[i - 1][j + 1]

.setText((bombButton[i - 1][j + 1].BombRoundCount)

+ "");

bombButton[i - 1][j + 1].setEnabled(false);

bombButton[i - 1][j + 1].isClicked = true;

}

}

if ((j - 1 >= 0)) { // 檢測左邊是否爲空

if (bombButton[i][j - 1].isBomb == false

&& bombButton[i][j - 1].isClicked == false

&& bombButton[i][j - 1].isRight == false) {

bombButton[i][j - 1]

.setText((bombButton[i][j - 1].BombRoundCount) + "");

bombButton[i][j - 1].setEnabled(false);

bombButton[i][j - 1].isClicked = true;

}

}

if ((i >= 0) && (j + 1 <= ((int) Math.sqrt(BlockNum) - 1))) { // 檢測右邊空格是不是空

if (bombButton[i][j + 1].isBomb == false

&& bombButton[i][j + 1].isClicked == false

&& bombButton[i][j + 1].isRight == false) {

bombButton[i][j + 1]

.setText((bombButton[i][j + 1].BombRoundCount) + "");

bombButton[i][j + 1].setEnabled(false);

bombButton[i][j + 1].isClicked = true;

}

}

if ((j - 1 >= 0) && (i + 1 <= ((int) Math.sqrt(BlockNum) - 1))) { // 檢測左下空格是不是空

if (bombButton[i + 1][j - 1].isBomb == false

&& bombButton[i + 1][j - 1].isClicked == false

&& bombButton[i + 1][j - 1].isRight == false) {

bombButton[i + 1][j - 1]

.setText((bombButton[i + 1][j - 1].BombRoundCount)

+ "");

bombButton[i + 1][j - 1].setEnabled(false);

bombButton[i + 1][j - 1].isClicked = true;

}

}

if ((i + 1 <= ((int) Math.sqrt(BlockNum) - 1))) { // 檢測下邊空格是不是空

if (bombButton[i + 1][j].isBomb == false

&& bombButton[i + 1][j].isClicked == false

&& bombButton[i + 1][j].isRight == false) {

bombButton[i + 1][j]

.setText((bombButton[i + 1][j].BombRoundCount) + "");

bombButton[i + 1][j].setEnabled(false);

bombButton[i + 1][j].isClicked = true;

}

}

if ((j + 1 <= ((int) Math.sqrt(BlockNum) - 1))

&& (i + 1 <= ((int) Math.sqrt(BlockNum) - 1))) { // 檢測右下邊空格是不是空

if (bombButton[i + 1][j + 1].isBomb == false

&& bombButton[i + 1][j + 1].isClicked == false

&& bombButton[i + 1][j + 1].isRight == false) {

bombButton[i + 1][j + 1]

.setText((bombButton[i + 1][j + 1].BombRoundCount)

+ "");

bombButton[i + 1][j + 1].setEnabled(false);

bombButton[i + 1][j + 1].isClicked = true;

}

}

if ((i - 1 >= 0) && (j - 1 >= 0))// 檢測左上

isNull(bombButton, bombButton[i - 1][j - 1]);

if ((i - 1 >= 0))

isNull(bombButton, bombButton[i - 1][j]);// 檢測上方

if ((i - 1 >= 0) && (j + 1 <= (int) Math.sqrt(BlockNum) - 1))

isNull(bombButton, bombButton[i - 1][j + 1]);// 檢測右上

if ((j - 1 >= 0))

isNull(bombButton, bombButton[i][j - 1]);// 檢測左邊

if ((i >= 0) && (j + 1 <= ((int) Math.sqrt(BlockNum) - 1)))

isNull(bombButton, bombButton[i][j + 1]);// 檢測右邊

if ((j - 1 >= 0) && (i + 1 <= ((int) Math.sqrt(BlockNum) - 1)))

isNull(bombButton, bombButton[i + 1][j - 1]); // 檢測左下

if ((i + 1 <= ((int) Math.sqrt(BlockNum) - 1))) // 檢測下

isNull(bombButton, bombButton[i + 1][j]);

if ((j + 1 <= ((int) Math.sqrt(BlockNum) - 1))

&& (i + 1 <= ((int) Math.sqrt(BlockNum) - 1))) // 檢測右下

isNull(bombButton, bombButton[i + 1][j + 1]); 

}

}

public void actionPerformed(ActionEvent e) {

CountRoundBomb();

if (((Bomb) e.getSource()).isBomb == false

&& ((Bomb) e.getSource()).isClicked == false) {

((Bomb) e.getSource())

.setText((((Bomb) e.getSource()).BombRoundCount) + "");

((Bomb) e.getSource()).isClicked = true;

((Bomb) e.getSource()).setIcon(null);

((Bomb) e.getSource()).setEnabled(false);

if ((((Bomb) e.getSource()).BombRoundCount) == 0)

isNull(bombButton, (Bomb) e.getSource());

isWin();

} else if (((Bomb) e.getSource()).isBomb == true) {

for (int i = 0; i < (int) Math.sqrt(BlockNum); i++)

for (int j = 0; j < (int) Math.sqrt(BlockNum); j++) {

if (bombButton[i][j].isBomb == true)

bombButton[i][j].setIcon(icon_bomb);

}

((Bomb) e.getSource()).setIcon(icon_bomb_big);

new JOptionPane();

JOptionPane.showMessageDialog(this, "你踩到地雷了,按肯定重來", "你踩到地雷了", 2);

replay();

}

}

public void mouseClicked(MouseEvent e) {

Bomb bombSource = (Bomb) e.getSource();

boolean right = SwingUtilities.isRightMouseButton(e);

if ((right == true) && (bombSource.isClicked == false)) {

bombSource.BombFlag = (bombSource.BombFlag + 1) % 3;

if (bombSource.BombFlag == 1) {

if (BombNum > 0 && bombSource.isRight == false) {

bombSource.setIcon(icon_flag);

bombSource.isRight = true;

BombNum--;

}

isWin();

nowBomb.setText("當前雷數" + " " + BombNum + "");

} else if (bombSource.BombFlag == 2) {

if ((BombNum != 0)

|| (BombNum == 0 && (bombSource.getIcon() == icon_flag)))

BombNum++;

bombSource.setIcon(icon_question);

nowBomb.setText("當前雷數" + " " + BombNum + "");

} else if (bombSource.BombFlag == 0) {

bombSource.setIcon(null);

bombSource.isRight = false;

}

}

}

public void mouseEntered(MouseEvent e) {

}

public void mouseReleased(MouseEvent e) {

}

public void mouseExited(MouseEvent e) {

}

public void mousePressed(MouseEvent e) {

}

}

/* 主類 *

public class MineSquare {

public static void main(String args[]) {

(new MainBomb()).setVisible(true);

}

}

最後調試結果以下圖:

項目開發時間

步驟

耗時(h)

百分比

需求分析

1

18%

設計

2

36%

代碼實現

1

18%

測試

1

18%

分析總結

0.5

10%

 

 

實驗總結

    在本次的實驗中在命令端輸入git status老是提示不存在,經過百度的出要先創建倉庫須要輸入git init;當輸入vi HelloWorld.java指令時出顯文本編輯剛開始不知道怎麼輸入,最後經過esc 、i、及wq將問題解決。在本次的試驗中小軟件的編寫存在問題,在編程方面還須要提升本身。在這三次的實驗中明顯能感受到和其餘同窗存在的差距,在之後的學習中應該多學、多問、多思。

相關文章
相關標籤/搜索