|
Consider this code. (Online at www.xp123.com/rwb)
Machine.java
public class Machine {
String name;
String location;
String bin;
public Machine(String name, String location) {
this.name = name;
this.location = location;
}
public String take() {
String result = bin;
bin = null;
return result;
}
public String bin() {
return bin;
}
public void put(String bin) {
this.bin = bin;
}
public String name() {return name;}
}
Robot.java
public class Robot {
Machine location;
String bin;
public Robot() {}
public Machine location() {return location;}
public void moveTo(Machine location) {this.location = location;}
public void pick() {this.bin = location.take();}
public String bin() {return bin;}
public void release() {
location.put(bin);
bin = null;
}
}
RobotTest.java
import junit.framework.*;
public class RobotTest extends TestCase{
public RobotTest(String name) {super(name);}
public void testRobot() {
Machine sorter = new Machine("Sorter", "left");
sorter.put("chips");
Machine oven = new Machine("Oven", "middle");
Robot robot = new Robot();
assertEquals("chips", sorter.bin());
assertNull(oven.bin());
assertNull(robot.location());
assertNull(robot.bin());
robot.moveTo(sorter);
robot.pick();
robot.moveTo(oven);
robot.release();
assertNull(robot.bin());
assertEquals(oven, robot.location());
assertNull(sorter.bin());
assertEuals("chips", oven.bin());
}
}
Report.java
import java.util.*;
import java.io.*;
public class Report {
public static void report(Writer out, List machines, Robot robot)
throws IOException
{
out.write("FACTORY REPORT\n");
Iterator line = machines.iterator();
while (line.hasNext()) {
Machine machine = (Machine) line.next();
out.write("Machine " + machine.name());
if (machine.bin() != null)
out.write(" bin=" + machine.bin());
out.write("\n");
}
out.write("\n");
out.write("Robot");
if (robot.location() != null)
out.write(" location=" + robot.location().name());
if (robot.bin() != null)
out.write(" bin=" + robot.bin());
out.write("\n");
out.write("========\n");
}
}
ReportTest.java
import junit.framework.TestCase;
import java.util.ArrayList;
import java.io.PrintStream;
import java.io.StringWriter;
import java.io.IOException;
public class ReportTest extends TestCase {
public ReportTest(String name) {super(name);}
public void testReport() throws IOException {
ArrayList line = new ArrayList();
line.add(new Machine("mixer", "left"));
Machine extruder = new Machine("extruder", "center");
extruder.put("paste");
line.add(extruder);
Machine oven = new Machine("oven", "right");
oven.put("chips");
line.add(oven);
Robot robot = new Robot();
robot.moveTo(extruder);
robot.pick();
StringWriter out = new StringWriter();
Report.report(out, line, robot);
String expected =
"FACTORY REPORT\n" +
"Machine mixer\nMachine extruder\n" +
"Machine oven bin=chips\n\n" +
"Robot location=extruder bin=paste\n" +
"========\n";
assertEquals(expected, out.toString());
}
}
In Report.java, circle four blocks of code to show which functions you might extract in the process of refactoring this code. Rewrite the report() method as four statements, as if you had done Extract Method for each block. Does it make sense to extract a one-line method? Long methods are trivially easy to spot, yet they seem to occur often in real code. Why?
See Appendix A for solutions.
|