我的java天地

          責(zé)任鏈模式

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

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

          責(zé)任鏈模式顧名思義,對(duì)一個(gè)請(qǐng)求設(shè)計(jì)出一個(gè)鏈狀的處理流程,處于鏈條上的每個(gè)類都可以處理這個(gè)請(qǐng)求,或者放棄對(duì)請(qǐng)求的處理然后交給鏈條上的下一個(gè)類。?

          一個(gè)"純粹"的責(zé)任鏈模式應(yīng)該是請(qǐng)求只能交給責(zé)任鏈上的一個(gè)類去處理,而不是每個(gè)類處理一部分,后者應(yīng)該叫變種的責(zé)任鏈。還是舉個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明吧,就舉一個(gè)產(chǎn)品的客戶打電話尋求幫助的例子吧。?

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

          下面貼一下實(shí)現(xiàn)的代碼,首先要有一系列的部門,這些部門就是責(zé)任鏈上的一系列類。?

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

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

          然后來(lái)看一個(gè)用戶請(qǐng)求的抽象,部門的具體實(shí)現(xiàn)會(huì)用到,這里先列出來(lái)。這個(gè)類本質(zhì)上不是cor的一個(gè)組成部分。
          ?1/**?
          ?2?*?客戶發(fā)出的請(qǐng)求類型<br>?
          ?3?*??
          ?4?*/
          ??
          ?5public?class?Request?{??
          ?6????public?enum?RequestType?{??
          ?7????????/**?產(chǎn)品錯(cuò)誤?*/??
          ?8????????ProductError,??
          ?9????????/**?功能使用?*/??
          10????????FunctionUsage,??
          11????????/**?其他請(qǐng)求?*/??
          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}
          ?

          下面來(lái)看幾個(gè)部門的具體實(shí)現(xiàn):
          /**?
          ?*?銷售部門<br>?
          ?*??
          ?
          */
          ??
          public?class?SalesDepartment?extends?Department?{??
          ??
          ????@Override??
          ????
          public?void?handleRequest(Request?request)?{??
          ????????
          /*?判斷請(qǐng)求的類型來(lái)決定哪種請(qǐng)求來(lái)自己處理,哪種拋給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");??
          ????????}
          ??
          ????}
          ??
          }
          ??
          ??
          ??
          /**?
          ?*?開(kāi)發(fā)部門<br>?
          ?*??
          ?
          */
          ??
          public?class?DevelopDepartment?extends?Department?{??
          ??
          ????@Override??
          ????
          public?void?handleRequest(Request?request)?{??
          ????????
          /*?判斷請(qǐng)求的類型來(lái)決定哪種請(qǐng)求來(lái)自己處理,哪種拋給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");??
          ????????}
          ??
          ????}
          ??
          ??
          }
          ?

          最后是調(diào)用它的客戶端代碼:?
          ?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}
          ?
          這樣,一個(gè)完整的責(zé)任鏈例子就寫完了。?


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

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

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(3)

          隨筆分類(144)

          隨筆檔案(157)

          相冊(cè)

          最新隨筆

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 常熟市| 双江| 章丘市| 湟中县| 新宁县| 镇远县| 田阳县| 靖江市| 开原市| 竹北市| 大关县| 大田县| 体育| 治县。| 铜山县| 军事| 萍乡市| 酒泉市| 克东县| 伽师县| 淮安市| 贵州省| 宜兰县| 北海市| 乌海市| 许昌市| 崇左市| 道孚县| 府谷县| 台北县| 从江县| 三原县| 白河县| 洛扎县| 汉源县| 长泰县| 常州市| 阜新| 什邡市| 来安县| 鄂伦春自治旗|