1

我想实现责任链模式,但似乎我缺少一些东西,因为在具体类中setnexthandler没有设置下一个,但始终是相同的。我想我的错误是在else state中的processMalfunction()方法的具体类next.setNextHandler(next);我认为它应该是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); 
    } 
} 

回答

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); 
+0

对不起,我没有提供我认为不需要的测试课程。我现在编辑它。 –

+0

但是,我的观点仍然存在:没有链接曾经呼吁链条中的下一个环节。链接不应该修改链条的结构:这不是它的责任。 –

+1

在你的评论中你已经提到了A Chain会尽自己的本分,然后转发给其他人,但更好的实现是,如果Chain不能执行那个任务,那么只有它转发。如果链可以处理请求,它将返回客户端。 – Atul