java 测试模式跟踪

阅读: 评论:0

java 测试模式跟踪

java 测试模式跟踪

标签:

实验内容

1. XP基础

2. XP核心实践

3. 相关工具

实验步骤

(一)敏捷开发与XP

软件工程包括下列领域:软件需求分析、软件设计、软件构建、软件测试和软件维护。

标识符名字应当直观且可以拼读,可望文知意,不必进行“解码”,一般采用英文单词或其组合,便于记忆和阅读,切忌使用汉语拼音来命名,用词要准确例如“当前值”应该起名currentValue,写成nowValue就不准确了,但还凑合,写成dqz(dang qian zhi 首字母)就是笑话了。

标识符的长度“min-length && max-information”的原则,比如:maxVal 比 maxValueUntilOverflow要好些,可以通过去元音法把变量名变短,如returnValue->rtnVal ,message->msg;一般全局变量用具有说明性的名字,局部变量用短名字:单字符的名字,常见的如i,j,k等用作局部变量。

(二)编码标准

编写代码一个重要的认识是“程序大多时候是给人看的”,编程标准使代码更容易阅读和理解,甚至可以保证其中的错误更少。编程标准包含:具有说明性的名字、清晰的表达式、直截了当的控制流、可读的代码和注释,以及在追求这些内容时一致地使用某些规则和惯用法的重要性。

标识符的长度“min-length && max-information”的原则,比如:maxVal 比 maxValueUntilOverflow要好些,可以通过去元音法把变量名变短,如returnValue->rtnVal ,message->msg;一般全局变量用具有说明性的名字,局部变量用短名字:单字符的名字,常见的如i,j,k等用作局部变量。

Java中的一般的命名规则有:

要体现各自的含义

包、类、变量用名词

方法名用动宾

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

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

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

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

(三)结对编程

武西垚工作:加注释,测试代码,加图片

郑伟:写主函数,完善各模块

结对同学:20135332

/

拼图游戏

* JAVA小游戏-拼图 我做的第一个小游戏 * Cell类是继承的按钮类,并加上相应图形,形成方格 *MyCanvas是一个面板,加载Cell类的对象(方格),是这三个类中的核心 *

*/

import java.awt.BorderLayout; import java.awt.Button; import java.awt.Choice; import java.awt.Color; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;

import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel;

public class MyMainFrame extends JFrame implements ActionListener { MyCanvas myCanvas; JPanel panelNorth,panelPreview;//定义上方的面板,及预览所需的面板 Button start,preview,set;//定义开始,预览,设定按钮 Container container;//容器,得到内容面板

public MyMainFrame() {//初使化 container&#ContentPane(); start=new Button("开始"); start.addActionListener(this); preview=new Button("预览"); preview.addActionListener(this); set = new Button("设置"); set.addActionListener(this); panelPreview=new JPanel(); panelPreview.setLayout(null); Icon icon=new ImageIcon("pictrue/pic_"+MyCanvas.pictureID+".jpg"); JLabel label=new JLabel(icon); label.setBounds(0,0,300,300); panelPreview.add(label);

panelNorth=new JPanel(); panelNorth.d); panelNorth.add(start); panelNorth.add(preview); panelNorth.add(set); myCanvas=new MyCanvas(); container.add(myCanvas,BorderLayout.CENTER); container.add(panelNorth,BorderLayout.NORTH); this.setTitle("拼图小游戏-明"); this.setLocation(300,200); this.setSize(308,365); this.setResizable(false); this.setVisible(true);

this.setDefaultCloseOperation(3); } public static void main(String[] args) { // TODO 自动生成方法存根 new MyMainFrame();

} public void actionPerformed(ActionEvent arg0) {//对三个按钮事件的处理 // TODO 自动生成方法存根 Button button=(Source(); if(button==start){ myCanvas.Start();

}else if(button==preview){ Label()=="预览"){ ve(myCanvas); container.add(panelPreview); panelPreview.updateUI(); paint();

button.setLabel("返回"); }else{ ve(panelPreview); container.add(myCanvas); paint(); button.setLabel("预览"); } }else if(button==set){//修改所选图片 Choice pic = new Choice(); pic.add("小猫"); pic.add("小猪"); pic.add("云"); pic.add("QQ"); pic.add("卡通"); pic.add("花");

int i=JOptionPane.showConfirmDialog(this,pic, "选择图片", JOptionPane.OK_CANCEL_OPTION); if(i==JOptionPane.YES_OPTION){ MyCanvas.pictureID&#SelectedIndex()+1; LoadPictrue(); Icon icon=new ImageIcon("pictrue/pic_"+MyCanvas.pictureID+".jpg"); JLabel label=new JLabel(icon); label.setBounds(0,0,300,300); veAll(); panelPreview.add(label); paint(); } } }

}

--------------------------------------------------

import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseListener;

import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JOptionPane; import javax.swing.JPanel;

public class MyCanvas extends JPanel implements MouseListener { boolean hasAddActionListener=false;//设置方格的动作监听器的标志位,TRUE为已经添加上动作事件,FALSE是尚未添加动作事件 Cell cell[];//定义方格 Rectangle cellNull;//定义空方格区域 public static int pictureID=1;//当前选择的图片代号 public MyCanvas() { this.setLayout(null); this.setSize(400,400); cellNull=new Rectangle(200,200,100,100);//空方格区域在第三行每三列 cell=new Cell[9]; Icon icon; for (int i = 0; i < 3; i++) {//为9个方格加载图片,并初使化坐标,形成三行三列 for(int j=0;j<3;j++){ icon=new ImageIcon("pictrue/pic_"+pictureID+"_"+(i*3+j+1)+".jpg"); cell[i*3+j]=new Cell(icon); cell[i*3+j].setLocation(j*100,i*100); this.add(cell[i*3+j]); } } ve(cell[8]);//移除最后一个多余的方格 }

public void reLoadPictrue(){//当选择其它图形进行拼图时,需重新加载新图片 Icon icon; for (int i = 0; i < 3; i++) { for(int j=0;j<3;j++){ icon=new ImageIcon("pictrue/pic_"+pictureID+"_"+(i*3+j+1)+".jpg"); cell[i*3+j].setIcon(icon); } } } public boolean isFinish(){//判断是否拼合成功 for(int i=0;i<8;i++){ int x=cell[i].getBounds().x; int y=cell[i].getBounds().y; if(y/100*3+x/100!=i) return false; } return true; }

public void Start(){//对方格进行重新排列,打乱顺序

while(cell[0].getBounds().x<=100&&cell[0].getBounds().y<=100){//当第一个方格距左上角较近时 int x&#Bounds().x; int y&#Bounds().y; int direction=(int)(Math.random()*4);//产生0-4,对应空方格的上下左右移动 if(direction==0){//空方格左移动,与左侧方格互换位置,左侧方格右移动 x-=100; if(test(x,y)){ for(int j=0;j<8;j++){ if((cell[j].getBounds().x==x)&&(cell[j].getBounds().y==y)){//依次寻找左侧的按钮 cell[j].move("RIGHT",100); cellNull.setLocation(x,y); break;//找到后跳出for循环 } } } }else if(direction==1){//RIGHT x+=100; if(test(x,y)){ for(int j=0;j<8;j++){ if((cell[j].getBounds().x==x)&&(cell[j].getBounds().y==y)){ cell[j].move("LEFT",100); cellNull.setLocation(x,y); break; } } } }else if(direction==2){//UP y-=100; if(test(x,y)){ for(int j=0;j<8;j++){ if((cell[j].getBounds().x==x)&&(cell[j].getBounds().y==y)){ cell[j].move("DOWN",100); cellNull.setLocation(x,y); break; } } } }else{//DOWN y+=100; if(test(x,y)){ for(int j=0;j<8;j++){ if((cell[j].getBounds().x==x)&&(cell[j].getBounds().y==y)){ cell[j].move("UP",100); cellNull.setLocation(x,y); break; } } } }

}

if(!hasAddActionListener)//如果尚未添加动作事件,则添加 for(int i=0;i<8;i++)//为第个方格添加动作事件,这样单击按钮就能移动了 cell[i].addMouseListener(this); hasAddActionListener=true; } private boolean test(int x,int y){ if((x>=0&&x<=200)||(y>=0&&y<=200)) return true; else return false; } //public void paint(Graphics g){ // //for(int i=0;i<=300;i+=100) //g.drawLine(0, i, 300, i); //for(int i=0;i<=300;i+=100) //g.drawLine(i, 0, i, 300); //for(int i=0;i<8;i++) //cell[i].repaint(); //}

public void mouseClicked(MouseEvent arg0) {} public void mouseEntered(MouseEvent arg0) {} public void mouseExited(MouseEvent arg0) {} public void mouseReleased(MouseEvent arg0) {} public void mousePressed(MouseEvent arg0) {//方格的鼠标事件,因为用到了MyCanvas中的一些方法,因此没有在Cell类中处理鼠标事件 Cell button=(Source(); int x1&#Bounds().x;//得到所单击方格的坐标 int y1&#Bounds().y;

int x2&#Bounds().x;//得到空方格的坐标 int y2&#Bounds().y;

if(x1==x2&&y1-y2==100)//进行比较,如果满足条件则进行交换 ve("UP",100); else if(x1==x2&&y1-y2==-100) ve("DOWN",100); else if(x1-x2==100&y1==y2) ve("LEFT",100); else if(x1-x2==-100&&y1==y2) ve("RIGHT",100); else return;//不满足就不进行任何处理

cellNull.setLocation(x1,y1); paint(); if(this.isFinish()){//进行是否完成的判断 JOptionPane.showMessageDialog(this,"恭喜你完成拼图,加油!"); for(int i=0;i<8;i++) cell[i].removeMouseListener(this);//如果已完成,撤消鼠标事件,鼠标单击方格不在起作用 hasAddActionListener=false; } }

}

------------------------------------------------------------------------------------------

import javax.swing.Icon; import javax.swing.JButton;

public class Cell extends JButton { Cell(Icon icon){//实际为ICON super(icon); this.setSize(100,100); }

public void move(String direction,int sleep){//方格的移动 if(direction=="UP"){ this.Bounds().Bounds().y-100); }else if(direction=="DOWN"){ this.Bounds().Bounds().y+100); }else if(direction=="LEFT"){ this.Bounds().Bounds().y); }else{ this.Bounds().x+Bounds().y); } }

}

(四)版本控制

注意一点,往代码库提交的代码一定编译、运行、测试都没有问题的代码,我们上面测试代码没有问题了,就可以提交了: 如图:我们可以先用git status查看一下代码状态,显示有未跟踪的代码,并建议用git add ...添加,我们使用git add HelloWorld.* 把要提交的文件的信息添加到索引库中。当我们使用git commit时,git将依据索引库中的内容来进行文件的提交。这只是在本地操作,关闭实验环境,会删除代码的,如果想把代码保存到远程托管服务器中,需要使用git push,实验完成前,一定不要忘了使用git push,否则就是相当于你在Word中编辑了半天文件最后却没有保存。 我们可以修改HelloWorld.java,如下图所示:

编译、运行、测试没有问题后进行提交,这儿使用的是git commit -a: ,

我们可以通过git log查看代码提

交记录:

(五)重构

我们先看看重构的概念:

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

重构中一个非常关键的前提就是“不改变软件外部行为”,它保证了我们在重构原有系统的同时,不会为原系统带来新的BUG,以确保重构的安全。如何保证不改变软件外部行为?重构后的代码要能通过单元测试。如何使其更加易于阅读、易于维护和易于变更?设计模式给出了重构的目标。

重构重要吗?你看看Eclipse菜单中有个refactor菜单就知道了,重构几乎是现代IDE的标配了:

我们在编码标准中说“给标识符命名”是程序员一项重要技能,以前没有这个意识,现在知道了怎么办?没问题,上图中重构的第一项功能就是Rename,可以给类、包、方法、变量改名字。 例如这有个ABC类:

这个类,类名,方法名和方法的参数名都有问题,没有注释的话是无法理解代码的。我们可以使用Eclipse中的重构功能来改名。修改方法是,用鼠标单击要改的名字,选择Eclipse中菜单中的Refactor-&:

重构完的效果如下:

功能不变,代码水平立马上了一个档次,体会到命名的威力了吧?

Eclipse中菜单中的Refactor->,如下图:

注意分析一下重构前后的代码变化: 同样可以封装id和age两个成员变量,结果如下:

上面第34,35行还是有问题的,每次打印学生信息都这么写代码违反了DRY原则,造成代码重复,正常的重构可以使用Eclipse中的,如下图:

由于Java中所有的类都有个专门的toString方法,我们使用Eclipse中Source->Generate toString()... 给Student类产生一个toString方法,如下图:

修改main的代码,结果如下:

大家想一想,这样重构后有什么好处?重构有什么问题吗?

我们要修改软件,万变不离其宗,无非就是四种动机:

增加新功能;

原有功能有BUG;

改善原有程序的结构;

优化原有系统的性能 。

最单纯的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与相应的重构手法如下表所示:

Eclipse中Refactor菜单中的重构手法的应用时机如下图所示:

更完整的手法可以参考《重构》作者Martin Fowler的博客。Eclipse中基本手法的使用大家可以参考任何人都可以重构来进行学习实践。

一个完整的重构流程包括:

从版本控制系统代码库中Check out code

读懂代码(包括测试代码)

发现bad smell

Refactoring

运行所有的Unit Tests

往代码库中Check in code

我们结合Git给出一个比较完整的例子。

(六)实践项目

1. 以结对编程的方式编写一个软件,Blog中要给出结对同学的Blog网址,可以拍照展现结对编程情况,可以参考一下其他学校的作业

结对同学:20135322

/

2.记录TDD和重构的过程,测试代码不要少于业务代码,Eclipse中refactor菜单下的重构技能不要少于5个

3.团队代码要使用git在实验楼中托管,要使用结对同学中的一个同学的账号托管。

4. 程序要有GUI界面,参考用户界面和用户体验

5.程序功能从豌豆荚游戏中选择一款用Java实现,注意:团队之间项目不能有重复,课代表协调一下。

标签:

本文发布于:2024-01-31 04:19:31,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170664597425409.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:模式   测试   java
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23