结对编程与TDD结合开发实践

        结对编译与TDD结合的方式是:首先,第一个人写一个失败的单元测试,第二个人写代码让这个单元测试通过,然后第二个人再写一个失败的单元测试,交给第一个人,他再写代码让其通过...依次交替,直至完成。写代码之前或完成编码单元测试通过后都可对代码进行重构。

训练题目:机器人探查火星

RobotTest.java

package com.study.robot.test;

import org.junit.Assert;
import org.junit.Test;

import com.study.robot.ControlCenter;
import com.study.robot.Position;
import com.study.robot.Robot;

public class RobotTest {

	@Test
	public void test_turn_left() {
		Position position = new Position(0, 0, "N");
		Robot robot = new Robot(position);

		robot.command("L");
		
		Position resultPosition = robot.position; 
		Assert.assertEquals(new Position(0, 0, "W"), resultPosition);
	}

	@Test
	public void test_turn_right() {
		Position position = new Position(0, 0, "N");
		Robot robot = new Robot(position);
		
		robot.command("R");
		
		Position resultPosition = robot.position;
		Assert.assertEquals(new Position(0, 0, "E"), resultPosition);
	}
	
	@Test
	public void test_when_given_0_0_S_position_turn_right() {
		Position position = new Position(0, 0, "S");
		Robot robot = new Robot(position);
		
		robot.command("R");
		
		Position resultPosition = robot.position;
		Assert.assertEquals(new Position(0, 0, "W"), resultPosition);
	}
	
	@Test
	public void test_when_given_0_0_S_position_and_turn_twice() {
		Position position = new Position(0, 0, "S");
		Robot robot = new Robot(position);

		robot.command("R");
		robot.command("R");
		Position resultPosition = robot.position;
		Assert.assertEquals(new Position(0, 0, "N"), resultPosition);
	}
	
	@Test
	public void test_when_given_0_0_N_move_and_no_turn() {
		Position position = new Position(0, 0, "N");
		Robot robot = new Robot(position);
		robot.command("M");
		Position resultPosition = robot.position;
		
		Assert.assertEquals(new Position(0, 1, "N"), resultPosition);
	}
	
	@Test
	public void test_when_given_0_0_E_move_and_no_turn() {
		Position position = new Position(0, 0, "E");
		Robot robot = new Robot(position);
		robot.command("M");
		
		Position resultPosition = robot.position;
		Assert.assertEquals(new Position(1, 0, "E"), resultPosition);
	}
	
	@Test
	public void test_when_given_0_0_S_move_then_return_0_0_S() {
		Position position = new Position(0, 0, "S");
		Robot robot = new Robot(position);
		robot.command("M");
		
		Position resultPosition = robot.position;
		Assert.assertEquals(new Position(0, 0, "S"), resultPosition);
	}
	
	@Test
	public void test_when_given_0_3_W_move_then_return_2_3_N() {
		Position position = new Position(0, 3, "W");
		Robot robot = new Robot(position);
		robot.command("M");
		robot.command("R");
		robot.command("R");
		robot.command("M");
		robot.command("M");
		robot.command("L");
		
		Position resultPosition = robot.position;
		Assert.assertEquals(new Position(2, 3, "N"), resultPosition);
	}
	
	@Test
	public void test_two_robots() {
		Position position = new Position(0, 0, "E");
		Robot robot1 = new Robot(position);
		Robot robot2 = new Robot(position);
		ControlCenter controlCenter = new ControlCenter();
		controlCenter.addRobots(robot1);
		controlCenter.addRobots(robot2);
		
		controlCenter.command("M");
		
		Assert.assertEquals(new Position(1, 0, "E"), robot1.position);
		Assert.assertEquals(new Position(1, 0, "E"), robot2.position);
	}
	
	@Test
	public void test_two_robots_turn_left_and_move() {
		Position position = new Position(0, 0, "E");
		Robot robot1 = new Robot(position);
		Robot robot2 = new Robot(position);
		ControlCenter controlCenter = new ControlCenter();
		controlCenter.addRobots(robot1);
		controlCenter.addRobots(robot2);
		
		controlCenter.command("L");
		controlCenter.command("M");
		
		Assert.assertEquals(new Position(0, 1, "N"), robot1.position);
		Assert.assertEquals(new Position(0, 1, "N"), robot2.position);
	}
}

Position.java

package com.study.robot;

public class Position {

	public int x;
	public int y;
	public String direction;
	
	public Position(int x, int y, String direction) {
		this.x = x;
		this.y = y;
		this.direction = direction;
	}
	
	public Position(){
		super();
	}
	
	@Override
	public boolean equals(Object object) {
		Position position = (Position)object;
		if(x != position.x){
			return false;
		}
		if(y != position.y){
			return false;
		}
		if(!direction.equals(position.direction)){
			return false;
		}
		return true;
	}
	
	public void operateX(Integer opx){
		if(opx == null) {
			return;
		}
		if(this.x == 0 && opx < 0) {
			return;
		}
		this.x += opx;
	}
	
	public void operateY(Integer opy) {
		if(opy == null) {
			return;
		}
		if(this.y == 0 && opy < 0) {
			return;
		}
		this.y += opy;
	}
}

ControlCenter.java

package com.study.robot;

import java.util.ArrayList;
import java.util.List;

/**
 * 采用命令模式实现
 */
public class ControlCenter {

	private List<Robot> robots = new ArrayList<Robot>();
	
	public void addRobots(Robot robot) {
		robots.add(robot);
	}
	
	public void command(String command) {
		for(Robot robot: robots) {
			robot.command(command);
		}
	}
}

Robot.java

package com.study.robot;

import java.util.HashMap;
import java.util.Map;

/**
 * 表驱动法实现命令的执行
 * 表驱动法是一种编程模式——从表中查找信息而不是使用逻辑语句(if或else)。如果逻辑很复杂,导致逻辑判断链很长,使用驱动表法有助于降低复杂度。否则,表驱动法只会增加复杂度。
 * 从表中查询条目有三种方法:
 * a.直接访问(Directory access)表
 * b.索引访问(Index access)表
 * c.阶梯访问(Stair-step access)表
 * 表中保存的可能是数据、函数指针,对象实例等(说明:如果保存的是对象实例的话,那就是命令模式)
 */
public class Robot {

	public Position position;

	private String DIRECTION_EAST = "E";
	private String DIRECTION_WEST = "W";
	private String DIRECTION_SOUTH = "S";
	private String DIRECTION_NORTH = "N";

	private String COMMAND_LEFT = "L";
	private String COMMAND_RIGHT = "R";
	private String COMMAND_MOVE = "M";
	
	Map<String,String> directionSearchTable = new HashMap<String,String>(){{
		put(DIRECTION_EAST+COMMAND_LEFT, DIRECTION_NORTH);
		put(DIRECTION_WEST+COMMAND_LEFT, DIRECTION_SOUTH);
		put(DIRECTION_SOUTH+COMMAND_LEFT, DIRECTION_EAST);
		put(DIRECTION_NORTH+COMMAND_LEFT, DIRECTION_WEST);
		
		put(DIRECTION_EAST+COMMAND_RIGHT, DIRECTION_SOUTH);
		put(DIRECTION_WEST+COMMAND_RIGHT, DIRECTION_NORTH);
		put(DIRECTION_SOUTH+COMMAND_RIGHT, DIRECTION_WEST);
		put(DIRECTION_NORTH+COMMAND_RIGHT, DIRECTION_EAST);
	}};
	
	Map<String,Integer> xSearchTable = new HashMap<String,Integer>(){{
		put(DIRECTION_EAST, new Integer(1));
		put(DIRECTION_WEST, new Integer(-1));
	}};
	
	Map<String,Integer> ySearchTable = new HashMap<String,Integer>(){{
		put(DIRECTION_SOUTH, new Integer(-1));
		put(DIRECTION_NORTH, new Integer(1));
	}};	

	public Robot(Position position) {
		this.position = new Position();
		this.position.x = position.x;
		this.position.y = position.y;
		this.position.direction = position.direction;
	}

	public void command(String command) {
		
		if(command.equals(COMMAND_LEFT) || command.equals(COMMAND_RIGHT)) {
			position.direction = directionSearchTable.get(position.direction+command);
		}
		if(command.equals(COMMAND_MOVE)){
			position.operateX(xSearchTable.get(position.direction));
			position.operateY(ySearchTable.get(position.direction));
		}
	}
}

猜你喜欢

转载自bijian1013.iteye.com/blog/2118937
今日推荐