我正在尝试实现责任链模式,但似乎我遗漏了一些东西,因为在具体的类中,setnexthandler没有设置下一个但总是相同的。我想我的错误是在else statems next.setNextHandler(next)中的processMalfunction()方法的具体类中;我认为它应该是next.setNextHandler(Severity.Medium)的第一个。所以这是代码,如果你可以看看。这是代码。
public interface MalfunctionHandler
{
public void processMalfunction(Malfunction malfunciton);
public void setNextHandler(MalfunctionHandler handler);
}
public enum Severity
{
TRIVIAL, LOW, MEDIUM, HIGH
}
public class Malfunction
{
/**
* severity is a type of Severity
*/
Severity severity;
/**
* @param description describes the severity of the problem
*/
String description;
Malfunction(Severity severity, String description)
{
if(description == null)
{
description = "No description available. Probably serious.";
}
if(description.isEmpty())
{
description = "No description available. Probably serious.";
}
this.severity = severity;
this.description = description;
}
public Severity getSeverity()
{
return severity;
}
public String getDescription()
{
return description;
}
public void setSeverity(Severity severity)
{
this.severity = severity;
}
public void setDescription(String description)
{
this.description = description;
}
}
public class SpaceMonkey implements MalfunctionHandler
{
Severity severity;
MalfunctionHandler next;
File read = new File("expected-bronze.txt");
File f = new File("log-bronze.txt");
SpaceMonkey(Severity severity)
{
this.severity = severity;
System.out.println(FileUtility.readFile(read));
}
@Override
public void processMalfunction(Malfunction malfunction)
{
if (malfunction.getSeverity() == Severity.LOW)
{
final String[] splits = FileUtility.readFile(read).split("problem.");
for (String asset : splits)
{
if (asset.contains("Space monkey"))
{
FileUtility.writeFile(f, asset + "problem.");
System.out.println(asset + "problem.");
}
}
}
else
{
next.setNextHandler(next);
}
}
@Override
public void setNextHandler(MalfunctionHandler next)
{
this.next = next;
}
}
public class ServiceRobot implements MalfunctionHandler
{
Severity severity;
MalfunctionHandler next;
File read = new File("expected-bronze.txt");
File f = new File("log-bronze.txt");
ServiceRobot(Severity severity)
{
this.severity = severity;
}
@Override
public void processMalfunction(Malfunction malfuntion)
{
if (this.severity == severity)
{
String[] splits = FileUtility.readFile(read).split("problem.");
for(String asset : splits)
{
if(asset.contains("Service robot"))
{
FileUtility.writeFile(f, asset + "problem.");
System.out.println(asset + "problem.");
}
}
}
else
{
next.setNextHandler(next);
}
}
@Override
public void setNextHandler(MalfunctionHandler next)
{
this.next = next;
}
}
public class Engineer implements MalfunctionHandler
{
Severity severity;
MalfunctionHandler next;
File read = new File("expected-bronze.txt");
Engineer(Severity severity)
{
this.severity = severity;
}
@Override
public void processMalfunction(Malfunction malfuntion)
{
File f = new File("log-bronze.txt");
if (this.severity == severity)
{
String[] splits = FileUtility.readFile(read).split("problem.");
for(String asset : splits)
{
if(asset.contains("Engineer"))
{
FileUtility.writeFile(f, asset + "problem.");
System.out.println(asset + "problem.");
}
}
}
else
{
next.setNextHandler(next);
}
}
@Override
public void setNextHandler(MalfunctionHandler next)
{
this.next = next;
}
}
public class Captain implements MalfunctionHandler
{
Severity severity;
MalfunctionHandler next;
File read = new File("expected-bronze.txt");
Captain(Severity severity)
{
this.severity = severity;
}
@Override
public void processMalfunction(Malfunction malfuntion)
{
File f = new File("log-bronze.txt");
if (this.severity == severity)
{
String[] splits = FileUtility.readFile(read).split("problem.");
for(String asset : splits)
{
if(asset.contains("Captain"))
{
FileUtility.writeFile(f, asset + "problem.");
System.out.println(asset + "problem.");
}
}
}
else
{
next.setNextHandler(next);
}
}
@Override
public void setNextHandler(MalfunctionHandler next)
{
this.next = next;
}
}
public class FileUtility
{
/** This method appends a single string to a text file.
*
* @param f The file to write to
* @param entry The string to append
*/
public static void writeFile(File f, String entry)
{
try
{
final BufferedWriter out = new BufferedWriter(new FileWriter(f, true));
out.write(entry);
out.close();
} catch (IOException e)
{
System.err.println("Problem writing to the file");
}
}
/** This method resets the named text file.
*
* @param f The file to reset
*/
public static void resetFile(File f) {
try {
final BufferedWriter out = new BufferedWriter(new FileWriter(f, false));
out.write("");
out.close();
} catch (IOException e) {
System.err.println("Problem reset the file");
}
}
/** This method reads the contents of a text file.
*
* @param f The file to read from
* @return the contents of the text file as a single string
*/
public static String readFile(File f) {
final StringBuilder sb = new StringBuilder();
try {
final Scanner scanner = new Scanner(f);
while (scanner.hasNextLine()) {
sb.append(scanner.nextLine());
}
scanner.close();
} catch (FileNotFoundException e) {
System.err.println("Problem reading from file");
}
return sb.toString();
}
}
public class MalfunctionHandlerTest {
/**
* No-args constructor.
*/
public MalfunctionHandlerTest() {
}
/**
* Test of processMalfunction method.
*/
@Test
public void testProcessMalfunction() {
// Instanciate malfunction handlers
final SpaceMonkey sm = new SpaceMonkey(Severity.TRIVIAL);
final ServiceRobot sr = new ServiceRobot(Severity.LOW);
final Engineer e = new Engineer(Severity.MEDIUM);
final Captain c = new Captain(Severity.HIGH);
// Construct chain of responsbility
sm.setNextHandler(sr);
sr.setNextHandler(e);
e.setNextHandler(c);
// Create malfunctions
final Malfunction m1 = new Malfunction(Severity.HIGH, "Life support error. Oxygen "
+ "Recycling unit damaged, running at half efficiency");
final Malfunction m2 = new Malfunction(Severity.LOW, "Communications error. Cannot "
+ "find Jazz FM");
final Malfunction m3 = new Malfunction(Severity.MEDIUM, "Power supply error. Solar Panel "
+ "2 damaged, running at 31.3333% efficiency");
final Malfunction m4 = new Malfunction(Severity.MEDIUM, "Thermal regulation error. Sensor "
+ "damaged, manual temperature regulation needed");
final Malfunction m5 = new Malfunction(Severity.TRIVIAL, "Trash can full on C-Desk.");
final Malfunction m6 = new Malfunction(Severity.LOW, "Shower plug hole full of monkey hair");
final Malfunction m7 = new Malfunction(Severity.HIGH, "Proximity alert. Collision imminent");
// Clean log file
FileUtility.resetFile(new File("log-bronze.txt"));
// Process malfunctions
sm.processMalfunction(m1);
sm.processMalfunction(m2);
sm.processMalfunction(m3);
sm.processMalfunction(m4);
sm.processMalfunction(m5);
sm.processMalfunction(m6);
sm.processMalfunction(m7);
// Check log file
final String actualOutput = FileUtility.readFile(new File("log-bronze.txt"));
final String expectedOutput = FileUtility.readFile(new File("expected-bronze.txt"));
assertEquals(actualOutput, expectedOutput);
}
}
答案 0 :(得分:5)
我在这里看不到任何链设置。模式的原则是让链的每个链接都起作用,然后以某种方式调用下一个链接。
因此,方法应如下所示:
public void processMalfunction(Malfunction malfunction) {
doSomething();
this.next.processMalfunction(malfunction);
}
当然,应该使用类似
之类的东西设置链Link1 start = new Link1();
Link2 link2 = new Link2();
start.setNextHandler(link2);
Link3 link3 = new Link3();
link2.setNextHandler(link3);
...
您当前的代码包括在某些条件为真时执行某些操作,否则将下一个处理程序的下一个处理程序分配给自身:
next.setNextHandler(next);