码迷,mamicode.com
首页 > 编程语言 > 详细

java实验三 敏捷开发与XP实践

时间:2015-06-05 06:21:53      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:

一、实验内容

 (一)敏捷开发与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中的一般的命名规则有:

  • 要体现各自的含义
  • 包、类、变量用名词
  • 方法名用动宾
  • 包名全部小写,如:io,awt
  • 类名第一个字母要大写,如:HelloWorldApp
  • 变量名第一个字母要小写,如:userName

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

技术分享

(三)结对编程

结对编程是XP中的重要实践。在结对编程模式下,一对程序员肩并肩、平等地、互补地进行开发工作。他们并排坐在一台电脑前,面对同一个显示器,使用同一个键盘、同一个鼠标一起工作。他们一起分析,一起设计,一起写测试用例,一起编码,一起做单元测试,一起做集成测试,一起写文档等。 结对编程中有两个角色:

  • 驾驶员(Driver)是控制键盘输入的人。
  • 领航员(Navigator)起到领航、提醒的作用。

如何结对编程,为何要结对编程,重点是:

  • 驾驶员:写设计文档,进行编码和单元测试等XP开发流程。
  • 领航员:审阅驾驶员的文档、驾驶员对编码等开发流程的执行;考虑单元测试的覆盖率;思考是否需要和如何重构;帮助驾驶员解决具体的技术问题。
  • 驾驶员和领航员不断轮换角色,不要连续工作超过一小时,每工作一小时休息15分钟。领航员要控制时间。
  • 主动参与。任何一个任务都首先是两个人的责任,也是所有人的责任。没有“我的代码”、“你的代码”或“他/她的代码”,只有“我们的代码”。
  • 只有水平上的差距,没有级别上的差异。两人结对,尽管可能大家的级别资历不同,但不管在分析、设计或编码上,双方都拥有平等的决策权利。

团队精神是好多地方都强调的一个精神,最小的团队就是一对一的二人团队了,培养团队精神从结对编程开始吧。社会生活中人与人相处最重要的是诚信,有同理心,互利。结对编程中大家会出现分歧,如何更有效地合作要做到对事不对人

(四)版本控制

XP的集体所有制意味着每个人都对所有的代码负责;这一点,反过来又意味着每个人都可以更改代码的任意部分。结对编程对这一实践贡献良多:借由在不同的结对中工作,所有的程序员都能看到完全的代码。集体所有制的一个主要优势是提升了开发程序的速度,因为一旦代码中出现错误,任何程序员都能修正它。 这意味着代码要放到一个大家都能方便获取的地方,我们叫代码仓库。这引出另外一个话题叫版本控制(Version Control)。

不论是对于团队还是个体,版本控制都提供了很多好处。

  • 版本控制提供项目级的      undo(撤销)      功能:      没有什么事情是终结版本, 任何错误必须很容易回滚。 假设你在使用世界上最复杂的文字处理系统。 它具备了所有的能想到的功能,就是没有支持 DELETE(删除) 键。想象你打字的时候得多么的谨慎和缓慢吧,      特别是一篇超大的文档的快临近末尾的时候, 一个不小心就要重头再来(试想你选中所有的文字, 不小心按了 DELETE 键, 因为没有撤销功能,只好重新录入)。编辑文字和版本控制相同,任何时候都需要回滚,无论是一个小时, 一天, 还是一周, 这让你的团队工作自由快速的工作, 而且对于修正错误也非常自信。
  • 版本控制允许多人在同一代码上工作,      只要遵守一定的控制原则就行。 再也不会发生诸如一个人覆盖了另一个人编辑的代码,导致那个人的修改无效这样的情况。
  • 版本控制系统保存了过去所作的修改的历史记录。如果你遭遇到一些惊讶的代码,通过版本控制系统可以很容易找出是谁干的, 修改了什么, 修改的时间, 如果幸运的话,还能找出原因。
  • 版本控制系统还支持在主线上开发的同时发布多个软件版本。在软件发布的时候也不需要整个团队的停止工作,不需要冻结代码。
  • 版本控制也是项目级的时间机器,你可以选择任何一个时间, 精确地查看项目在当时的情况。 这对研究非常有用, 也是重现以前某个有问题的发布版本的基础。

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;
    }
 
}
四、运行结果截图:
技术分享
技术分享
技术分享
技术分享
技术分享

(七)总结

通过结对项目,我认识到了合作的重要性,紧密的合作能够提高我们的能力。代码测试过程中出现很多错误,但经过互相的合作和探讨,加以改进,便可以成功运行。

 

java实验三 敏捷开发与XP实践

标签:

原文地址:http://www.cnblogs.com/20135336wwz/p/4553524.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!