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