日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式之职责链模式

發(fā)布時(shí)間:2024/8/26 asp.net 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式之职责链模式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

定義:使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免了請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有對(duì)象處理它為止。

類型:行為類模式

類圖:

責(zé)任連模式的結(jié)構(gòu)

??????? 責(zé)任連模式的類圖非常簡單,它由一個(gè)抽象地處理類和它的一組實(shí)現(xiàn)類組成:

  • 抽象處理類:抽象處理類中主要包含一個(gè)指向下一處理類的成員變量nextHandler和一個(gè)處理請(qǐng)求的方法handRequest,handRequest方法的主要主要思想是,如果滿足處理的條件,則有本處理類來進(jìn)行處理,否則由nextHandler來處理。
  • 具體處理類:具體處理類主要是對(duì)具體的處理邏輯和處理的適用條件進(jìn)行實(shí)現(xiàn)。

適用場景:

1、有多個(gè)的對(duì)象可以處理一個(gè)請(qǐng)求,哪個(gè)對(duì)象處理該請(qǐng)求運(yùn)行時(shí)刻自動(dòng)確定;

2、在不明確指定接收者的情況下,向多個(gè)對(duì)象中的一個(gè)提交一個(gè)請(qǐng)求;

3、處理一個(gè)請(qǐng)求的對(duì)象集合應(yīng)被動(dòng)態(tài)指定。

在職責(zé)鏈模式里,很多對(duì)象由每一個(gè)對(duì)象對(duì)其下家的引用而連接起來形成一條鏈。請(qǐng)求在這個(gè)鏈上傳遞,直到鏈上的某一個(gè)對(duì)象決定處理此請(qǐng)求。發(fā)出這個(gè)請(qǐng)求的客戶端并不知道鏈上的哪一個(gè)對(duì)象最終處理這個(gè)請(qǐng)求,這使得系統(tǒng)可以在不影響客戶端的情況下動(dòng)態(tài)地重新組織鏈和分配責(zé)任。

?

職責(zé)鏈模式的主要優(yōu)點(diǎn)在于可以降低系統(tǒng)的耦合度,簡化對(duì)象的相互連接,同時(shí)增強(qiáng)給對(duì)象指派職責(zé)的靈活性,增加新的請(qǐng)求處理類也很方便;其主要缺點(diǎn)在于不能保證請(qǐng)求一定被接收,且對(duì)于比較長的職責(zé)鏈,請(qǐng)求的處理可能涉及到多個(gè)處理對(duì)象,系統(tǒng)性能將受到一定影響,而且在進(jìn)行代碼調(diào)試時(shí)不太方便。

在大學(xué)里面當(dāng)班干部,時(shí)常要向上級(jí)申請(qǐng)各方面的東西。譬如申請(qǐng)全班外出秋游,普通同學(xué)將申請(qǐng)表交給班長,班長簽字之后交給輔導(dǎo)員,輔導(dǎo)員批準(zhǔn)之后上交到主任辦公室…就是這樣,一個(gè)請(qǐng)求(這里是一份申請(qǐng)表)有時(shí)候需要經(jīng)過好幾個(gè)級(jí)別的處理者(這里是輔導(dǎo)員、主任)的審查才能夠最終被確定可行與否。

在這里表現(xiàn)出來的是一個(gè)職責(zé)鏈,即不同的處理者對(duì)同一個(gè)請(qǐng)求可能擔(dān)負(fù)著不同的處理方式、權(quán)限,但是我們希望這個(gè)請(qǐng)求必須到達(dá)最終拍板的處理者(否則秋游就沒戲了)。這種關(guān)系就很適合使用職責(zé)鏈模式了。

類圖結(jié)構(gòu)如下:

?代碼實(shí)現(xiàn)如下:

  • //?全局變量,接口類型 ?
  • /** ?
  • ?*?使用Java中的interface定義全局變量,可根據(jù)具體需要在? ?
  • ?*?具體的包中使用靜態(tài)導(dǎo)入相關(guān)的全局變量,語法如下:? ?
  • ?*??import?static?package01.package02.*; ?
  • ?*/?
  • interface?Levels?{ ?
  • ????public?static?final?int?LEVEL_01?=?1; ?
  • ????public?static?final?int?LEVEL_02?=?2; ?
  • ????public?static?final?int?LEVEL_03?=?3; ?
  • }?
  • ?

  • //?抽象請(qǐng)求類 ?
  • abstract?class?AbstractRequest?{ ?
  • ????private?String?content?=?null; ?
  • ?
  • ????public?AbstractRequest(String?content)?{ ?
  • ????????this.content?=?content; ?
  • ????} ?
  • ?
  • ????public?String?getContent()?{ ?
  • ????????return?this.content; ?
  • ????} ?
  • ?
  • ????//?獲得請(qǐng)求的級(jí)別 ?
  • ????public?abstract?int?getRequestLevel(); ?
  • }?
  • ?

  • //?具體請(qǐng)求類01 ?
  • class?Request01?extends?AbstractRequest?{ ?
  • ????public?Request01(String?content)?{ ?
  • ????????super(content); ?
  • ????} ?
  • ?
  • ????@Override?
  • ????public?int?getRequestLevel()?{ ?
  • ????????return?Levels.LEVEL_01; ?
  • ????} ?
  • } ?
  • ?
  • //?具體請(qǐng)求類02 ?
  • class?Request02?extends?AbstractRequest?{ ?
  • ????public?Request02(String?content)?{ ?
  • ????????super(content); ?
  • ????} ?
  • ?
  • ????@Override?
  • ????public?int?getRequestLevel()?{ ?
  • ????????return?Levels.LEVEL_02; ?
  • ????} ?
  • } ?
  • ?
  • //?具體請(qǐng)求類03 ?
  • class?Request03?extends?AbstractRequest?{ ?
  • ????public?Request03(String?content)?{ ?
  • ????????super(content); ?
  • ????} ?
  • ?
  • ????@Override?
  • ????public?int?getRequestLevel()?{ ?
  • ????????return?Levels.LEVEL_03; ?
  • ????} ?
  • }?
  • ?

  • //?抽象處理者類, ?
  • abstract?class?AbstractHandler?{ ?
  • ????//?責(zé)任鏈的下一個(gè)節(jié)點(diǎn),即處理者 ?
  • ????private?AbstractHandler?nextHandler?=?null; ?
  • ?
  • ????//?捕獲具體請(qǐng)求并進(jìn)行處理,或是將請(qǐng)求傳遞到責(zé)任鏈的下一級(jí)別 ?
  • ????public?final?void?handleRequest(AbstractRequest?request)?{ ?
  • ?
  • ????????//?若該請(qǐng)求與當(dāng)前處理者的級(jí)別層次相對(duì)應(yīng),則由自己進(jìn)行處理 ?
  • ????????if?(this.getHandlerLevel()?==?request.getRequestLevel())?{ ?
  • ????????????this.handle(request); ?
  • ????????}?else?{ ?
  • ????????????//?當(dāng)前處理者不能勝任,則傳遞至職責(zé)鏈的下一節(jié)點(diǎn) ?
  • ????????????if?(this.nextHandler?!=?null)?{ ?
  • ????????????????System.out.println("當(dāng)前?處理者-0"?+?this.getHandlerLevel() ?
  • ????????????????????????+?"?不足以處理?請(qǐng)求-0"?+?request.getRequestLevel()); ?
  • ???????????????? ?
  • ????????????????//?這里使用了遞歸調(diào)用 ?
  • ????????????????this.nextHandler.handleRequest(request); ?
  • ????????????}?else?{ ?
  • ????????????????System.out.println("職責(zé)鏈上的所有處理者都不能勝任該請(qǐng)求..."); ?
  • ????????????} ?
  • ????????} ?
  • ????} ?
  • ?
  • ????//?設(shè)置責(zé)任鏈中的下一個(gè)處理者 ?
  • ????public?void?setNextHandler(AbstractHandler?nextHandler)?{ ?
  • ????????this.nextHandler?=?nextHandler; ?
  • ????} ?
  • ?
  • ????//?獲取當(dāng)前處理者的級(jí)別 ?
  • ????protected?abstract?int?getHandlerLevel(); ?
  • ?
  • ????//?定義鏈中每個(gè)處理者具體的處理方式 ?
  • ????protected?abstract?void?handle(AbstractRequest?request); ?
  • }?
  • ?

  • //?具體處理者-01 ?
  • class?Handler01?extends?AbstractHandler?{ ?
  • ????@Override?
  • ????protected?int?getHandlerLevel()?{ ?
  • ????????return?Levels.LEVEL_01; ?
  • ????} ?
  • ?
  • ????@Override?
  • ????protected?void?handle(AbstractRequest?request)?{ ?
  • ????????System.out.println("處理者-01?處理?"?+?request.getContent()?+?"\n"); ?
  • ????} ?
  • } ?
  • ?
  • //?具體處理者-02 ?
  • class?Handler02?extends?AbstractHandler?{ ?
  • ????@Override?
  • ????protected?int?getHandlerLevel()?{ ?
  • ????????return?Levels.LEVEL_02; ?
  • ????} ?
  • ?
  • ????@Override?
  • ????protected?void?handle(AbstractRequest?request)?{ ?
  • ????????System.out.println("處理者-02?處理?"?+?request.getContent()+?"\n"); ?
  • ????} ?
  • } ?
  • ?
  • //?具體處理者-03 ?
  • class?Handler03?extends?AbstractHandler?{ ?
  • ????@Override?
  • ????protected?int?getHandlerLevel()?{ ?
  • ????????return?Levels.LEVEL_03; ?
  • ????} ?
  • ?
  • ????@Override?
  • ????protected?void?handle(AbstractRequest?request)?{ ?
  • ????????System.out.println("處理者-03?處理?"?+?request.getContent()+?"\n"); ?
  • ????} ?
  • }?
  • ?

  • //?測試類 ?
  • public?class?Client?{ ?
  • ????public?static?void?main(String[]?args)?{ ?
  • ????????//?創(chuàng)建指責(zé)鏈的所有節(jié)點(diǎn) ?
  • ????????AbstractHandler?handler01?=?new?Handler01(); ?
  • ????????AbstractHandler?handler02?=?new?Handler02(); ?
  • ????????AbstractHandler?handler03?=?new?Handler03(); ?
  • ?
  • ????????//?進(jìn)行鏈的組裝,即頭尾相連,一層套一層 ?
  • ????????handler01.setNextHandler(handler02); ?
  • ????????handler02.setNextHandler(handler03); ?
  • ?
  • ????????//?創(chuàng)建請(qǐng)求并提交到指責(zé)鏈中進(jìn)行處理 ?
  • ????????AbstractRequest?request01?=?new?Request01("請(qǐng)求-01"); ?
  • ????????AbstractRequest?request02?=?new?Request02("請(qǐng)求-02"); ?
  • ????????AbstractRequest?request03?=?new?Request03("請(qǐng)求-03"); ?
  • ???????? ?
  • ????????//?每次提交都是從鏈頭開始遍歷 ?
  • ????????handler01.handleRequest(request01); ?
  • ????????handler01.handleRequest(request02); ?
  • ????????handler01.handleRequest(request03); ?
  • ????} ?
  • }?
  • 測試結(jié)果:

  • 處理者-01?處理?請(qǐng)求-01?
  • ?
  • 當(dāng)前?處理者-01?不足以處理?請(qǐng)求-02?
  • 處理者-02?處理?請(qǐng)求-02?
  • ?
  • 當(dāng)前?處理者-01?不足以處理?請(qǐng)求-03?
  • 當(dāng)前?處理者-02?不足以處理?請(qǐng)求-03?
  • 處理者-03?處理?請(qǐng)求-03?
  • 在上面抽象處理者 AbstractHandler 類的 handleRequest() 方法中,被 protected 修飾,并且該方法中調(diào)用了兩個(gè)必須被子類覆蓋實(shí)現(xiàn)的抽象方法,這里是使用了模板方法模式(Template Mehtod)。其實(shí)在這里,抽象父類的 handleRequest() 具備了請(qǐng)求傳遞的功能,即對(duì)某些請(qǐng)求不能處理時(shí),馬上提交到下一結(jié)點(diǎn)(處理者)中,而每個(gè)具體的處理者僅僅完成了具體的處理邏輯,其他的都不用理。 記得第一次看到職責(zé)鏈模式的時(shí)候,我很驚訝于它能夠把我們平時(shí)在代碼中的 if..else.. 的語句塊變成這樣靈活、適應(yīng)變化。例如:如果現(xiàn)在輔導(dǎo)員請(qǐng)長假了,但我們的秋游還是要爭取申請(qǐng)成功呀,那么我們?cè)?Client 類中可以不要?jiǎng)?chuàng)建 handler02,即不要將該處理者組裝到職責(zé)鏈中。這樣子處理比 if..else..好多了。或者說,突然來了個(gè)愛管閑事的領(lǐng)導(dǎo),那么我照樣可以將其組裝到職責(zé)鏈中。 關(guān)于上面使用場景中提到的3個(gè)點(diǎn): 1、處理者在運(yùn)行時(shí)動(dòng)態(tài)確定其實(shí)是我們?cè)?Client 中組裝的鏈所引起的,因?yàn)榫唧w的職責(zé)邏輯就在鏈中一一對(duì)應(yīng)起來; 2、因?yàn)椴淮_定請(qǐng)求的具體處理者是誰,所以我們把所有可能的處理者組裝成一條鏈,在遍歷的過程中就相當(dāng)于向每個(gè)處理者都提交了這個(gè)請(qǐng)求,等待其審查。并且在審查過程中,即使不是最終處理者,也可以進(jìn)行一些請(qǐng)求的“包裝”操作(這種功能類似于裝飾者模式),例如上面例子中的簽名批準(zhǔn); 3、處理者集合的動(dòng)態(tài)指定跟上面的第1、2點(diǎn)類似,即在 Client 類中創(chuàng)建了所有可能的處理者。 不足之處:

    1、對(duì)于每一個(gè)請(qǐng)求都需要遍歷職責(zé)鏈,性能是個(gè)問題;

    2、抽象處理者 AbstractHandler 類中的 handleRequest() 方法中使用了遞歸,棧空間的大小也是個(gè)問題。

    ?

    參考:http://blog.csdn.net/zhengzhb/article/details/7568676

    http://haolloyin.blog.51cto.com/1177454/342166/

    http://blog.csdn.net/qq7342272/article/details/6921524

    http://blog.csdn.net/hguisu/article/details/7547231

    http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html

    http://www.cnblogs.com/xudong-bupt/p/3617860.html

    轉(zhuǎn)載于:https://www.cnblogs.com/manmanlu/p/5732979.html

    總結(jié)

    以上是生活随笔為你收集整理的设计模式之职责链模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。