我的java天地

          責任鏈模式

          1. 責任鏈模式(Chain of Responsibility Pattern)?

          如果您看過Tomcat的源代碼,一定對里邊的管道模式(Pipeline)記憶猶新;如果您了解Servlet規范的話,一定會知道Filter;如果您使用過Struts2的話,一定清楚無處不在的interceptor。上邊的這些概念可以說都是責任鏈模式的抽象,或者說變種,下面我們就來看一下"原生態"的責任鏈模式。?

          責任鏈模式顧名思義,對一個請求設計出一個鏈狀的處理流程,處于鏈條上的每個類都可以處理這個請求,或者放棄對請求的處理然后交給鏈條上的下一個類。?

          一個"純粹"的責任鏈模式應該是請求只能交給責任鏈上的一個類去處理,而不是每個類處理一部分,后者應該叫變種的責任鏈。還是舉個簡單的例子來說明吧,就舉一個產品的客戶打電話尋求幫助的例子吧。?

          假如客戶買了某公司的一個產品,可是發現產品出了問題,于是打電話到部門A詢問,部門A告訴他去問一下部門B,部門B再讓他問一下部門C...... 以此類推,最后部門Z終于給他解決了問題。?

          下面貼一下實現的代碼,首先要有一系列的部門,這些部門就是責任鏈上的一系列類。?

          第一個是部門的基類:?
          ?1/**?
          ?2?*?部門基類<br>?
          ?3?*??
          ?4?*/
          ??
          ?5public?abstract?class?Department?{??
          ?6??
          ?7????protected?Department?successor;??
          ?8??
          ?9????/**?
          10?????*?處理方法,調用此方法處理請求?
          11?????*/
          ??
          12????public?abstract?void?handleRequest();??
          13??
          14????/**?
          15?????*?賦值方法,調用此方法設置下家?
          16?????*??
          17?????*?@param?successor?
          18?????*/
          ??
          19????public?void?setSuccessor(Department?successor)?{??
          20????????this.successor?=?successor;??
          21????}
          ??
          22??
          23????/**?
          24?????*?取值方法,得到下家對象?
          25?????*??
          26?????*?@return?
          27?????*/
          ??
          28????public?Department?getSuccessor()?{??
          29????????return?successor;??
          30????}
          ??
          31}
          ??

          后邊的部門子類都要繼承這個類,然后覆蓋handleRequest方法去處理用戶請求,另外,successor是指如果這個部門不能處理的話,將請求轉接給的下一個部門。?

          然后來看一個用戶請求的抽象,部門的具體實現會用到,這里先列出來。這個類本質上不是cor的一個組成部分。
          ?1/**?
          ?2?*?客戶發出的請求類型<br>?
          ?3?*??
          ?4?*/
          ??
          ?5public?class?Request?{??
          ?6????public?enum?RequestType?{??
          ?7????????/**?產品錯誤?*/??
          ?8????????ProductError,??
          ?9????????/**?功能使用?*/??
          10????????FunctionUsage,??
          11????????/**?其他請求?*/??
          12????????Others??
          13????}
          ??
          14??
          15????private?RequestType?type;??
          16??
          17????public?Request(RequestType?type)?{??
          18????????this.type?=?type;??
          19????}
          ??
          20??
          21????public?RequestType?getType()?{??
          22????????return?type;??
          23????}
          ??
          24??
          25}
          ?

          下面來看幾個部門的具體實現:
          /**?
          ?*?銷售部門<br>?
          ?*??
          ?
          */
          ??
          public?class?SalesDepartment?extends?Department?{??
          ??
          ????@Override??
          ????
          public?void?handleRequest(Request?request)?{??
          ????????
          /*?判斷請求的類型來決定哪種請求來自己處理,哪種拋給Successor?*/??
          ????????
          if?(request.getType()?==?Request.RequestType.FunctionUsage)?{??
          ????????????System.out.println(
          "SalesDepartment:?The?request?is?handled?here.");??
          ????????}
          ?else?if?(getSuccessor()?!=?null)?{??
          ????????????getSuccessor().handleRequest(request);??
          ????????}
          ?else?{??
          ????????????System.out.println(
          "The?request?cannot?be?handled");??
          ????????}
          ??
          ????}
          ??
          }
          ??
          ??
          ??
          /**?
          ?*?開發部門<br>?
          ?*??
          ?
          */
          ??
          public?class?DevelopDepartment?extends?Department?{??
          ??
          ????@Override??
          ????
          public?void?handleRequest(Request?request)?{??
          ????????
          /*?判斷請求的類型來決定哪種請求來自己處理,哪種拋給Successor?*/??
          ????????
          if?(request.getType()?==?Request.RequestType.ProductError)?{??
          ????????????System.out.println(
          "DevelopDepartment:?The?request?is?handled?here.");??
          ????????}
          ?else?if?(getSuccessor()?!=?null)?{??
          ????????????getSuccessor().handleRequest(request);??
          ????????}
          ?else?{??
          ????????????System.out.println(
          "The?request?cannot?be?handled");??
          ????????}
          ??
          ????}
          ??
          ??
          }
          ?

          最后是調用它的客戶端代碼:?
          ?1public?class?Client?{??
          ?2??
          ?3????/**?
          ?4?????*?@param?args?
          ?5?????*/
          ??
          ?6????public?static?void?main(String[]?args)?{??
          ?7????????Department?sales?=?new?SalesDepartment();??
          ?8????????Department?develop?=?new?DevelopDepartment();??
          ?9??????????
          10????????sales.setSuccessor(develop);??
          11??????????
          12????????Request?funcReq?=?new?Request(Request.RequestType.FunctionUsage);??
          13????????Request?errorReq?=?new?Request(Request.RequestType.ProductError);??
          14????????Request?otherReq?=?new?Request(Request.RequestType.Others);??
          15??????????
          16????????sales.handleRequest(funcReq);??
          17????????sales.handleRequest(errorReq);??
          18????????sales.handleRequest(otherReq);??
          19????}
          ??
          20??
          21}
          ?
          這樣,一個完整的責任鏈例子就寫完了。?


          posted on 2011-05-18 14:57 tobyxiong 閱讀(3545) 評論(0)  編輯  收藏 所屬分類: java

          <2011年5月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統計

          常用鏈接

          留言簿(3)

          隨筆分類(144)

          隨筆檔案(157)

          相冊

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 望都县| 安化县| 阿图什市| 苗栗县| 黎城县| 裕民县| 浠水县| 哈密市| 临漳县| 瑞安市| 安仁县| 石泉县| 通海县| 邻水| 嘉义市| 多伦县| 囊谦县| 吉隆县| 新宁县| 德清县| 龙山县| 界首市| 孟连| 株洲县| 北京市| 宣恩县| 辽阳市| 平塘县| 河津市| 南漳县| 深州市| 东平县| 琼结县| 长治市| 宁明县| 什邡市| 保定市| 大兴区| 托克托县| 平陆县| 肥乡县|