Java設計模式之《職責鏈模式》及應用場景

原創做品,能夠轉載,可是請標註出處地址:http://www.cnblogs.com/V1haoge/p/6530089.htmlhtml

  職責鏈模式(稱責任鏈模式)將請求的處理對象像一條長鏈通常組合起來,造成一條對象鏈。請求並不知道具體執行請求的對象是哪個,這樣就實現了請求與處理對象之間的解耦。設計模式

  生活中這種狀況其實很常見,公司部門之中,政府部門之中都有體現,在公司部門中,當你提交一份請求文件給你的直接上級時,你的直接上級能夠處理這個文件,若他以爲本身不夠資格,會將文件傳遞爲他的直接上級,這樣文件請求在這條鏈中傳遞,直到被某位感受本身足夠資格處理文件的人給處理掉爲止,在政府部門也是如此。ide

  職責鏈模式須要一個總接口,用來定義處理對象的公共部分(通常使用抽象類來定義),公共部分包括:一個後繼處理器,設置和獲取後繼處理器的方法,具體的請求處理方法(這個方法須要在每一個具體處理對象中實現),這裏定義爲抽象方法。測試

  咱們就以公司部門爲例來進行實例:this

領導抽象類:Lingdaospa

 1 public abstract class Lingdao {
 2     private Lingdao nextLingdao;
 3     public Lingdao getNextLingdao() {
 4         return nextLingdao;
 5     }
 6     public void setNextLingdao(Lingdao nextLingdao) {
 7         this.nextLingdao = nextLingdao;
 8     }
 9     abstract void chuli(Files file);
10 }

領導實現類:Zongjingli、Fujingli、Bumenjingli設計

 1 /**
 2  * 總經理
 3  */
 4 public class Zongjingli extends Lingdao {
 5     private final String name = "總經理";
 6     private final int level = 0;//最大
 7     @Override
 8     public void chuli(Files file) {
 9         if(this.level > file.getLevel()){
10             System.out.println(name + "未處理文件《" + file.getFileName() + "》");
11             getNextLingdao().chuli(file);
12         }else{
13             System.out.println(name + "處理了文件《" + file.getFileName() + "》");
14         }
15     }
16 }
17 
18 /**
19  * 副經理
20  */
21 public class Fujingli extends Lingdao {
22     private final String name = "副經理";
23     private final int level = 1;
24     @Override
25     public void chuli(Files file) {
26         if(this.level > file.getLevel()){
27             System.out.println(name + "未處理文件《" + file.getFileName() + "》");
28             getNextLingdao().chuli(file);
29         }else{
30             System.out.println(name + "處理了文件《" + file.getFileName() + "》");
31         }
32     }
33 }
34 
35 /**
36  * 部門經理
37  */
38 public class Bumenjingli extends Lingdao{
39     private final String name = "部門經理";
40     private final int level = 2;
41     @Override
42     public void chuli(Files file) {
43         if(this.level > file.getLevel()){
44             System.out.println(name + "未處理文件《" + file.getFileName() + "》");
45             getNextLingdao().chuli(file);
46         }else{
47             System.out.println(name + "處理了文件《" + file.getFileName() + "》");
48         }
49     }
50 }

文件類:Files代理

 1 public class Files {
 2     private String fileName;
 3     private int level;
 4     public String getFileName() {
 5         return fileName;
 6     }
 7     public void setFileName(String fileName) {
 8         this.fileName = fileName;
 9     }
10     public int getLevel() {
11         return level;
12     }
13     public void setLevel(int level) {
14         this.level = level;
15     }
16 }

測試類:Clientercode

 1 public class Clienter {
 2     public static void main(String[] args) {
 3         //定義職責鏈
 4         Lingdao zongjingli = new Zongjingli();
 5         Lingdao fujingli = new Fujingli();
 6         Lingdao bumenjingli = new Bumenjingli();
 7         bumenjingli.setNextLingdao(fujingli);
 8         fujingli.setNextLingdao(zongjingli);
 9         //定義兩份文件
10         Files f1 = new Files();
11         f1.setFileName("正確對待旱鴨子");
12         f1.setLevel(1);
13         Files f2 = new Files();
14         f2.setFileName("年會在那裏舉行");
15         f2.setLevel(0);
16         //提交文件
17         bumenjingli.chuli(f1);
18         bumenjingli.chuli(f2);
19     }
20 }

執行結果:htm

部門經理未處理文件《正確對待旱鴨子》
副經理處理了文件《正確對待旱鴨子》
部門經理未處理文件《年會在那裏舉行》
副經理未處理文件《年會在那裏舉行》
總經理處理了文件《年會在那裏舉行》

  實例清晰易懂,職責鏈的模式重在這個鏈的組成,如何組成鏈呢?

    第一步須要在處理者對象類中定義後繼處理者對象,將這部分代碼抽象到抽象類中實現,下降了代碼重複性。

    第二步就是在處理者對象類中的處理方法中若是當前處理者對象沒法處理,就將其傳遞到後繼對象去處理。

    第三步就是在測試類中將這些處理者類的實例串聯成鏈。

  其實這個模式有個缺陷,那就是雖然能夠實現請求額度傳遞,可是也不保證在這裏鏈中必定存在能處理請求的處理這類,一旦不存在,那麼這個請求將一直存在與鏈中,若是將鏈設置成環形,那麼這個請求將會永遠在環形鏈中傳遞不休;還有一點就是因爲請求的傳遞,請求沒法當即精確的找處處理者,處理效率會下降。


同系列文章:

相關文章
相關標籤/搜索