Java通俗易懂系列設(shè)計(jì)模式之責(zé)任鏈模式
責(zé)任鏈設(shè)計(jì)模式是行為設(shè)計(jì)模式之一。
責(zé)任鏈模式用于在軟件設(shè)計(jì)中實(shí)現(xiàn)松散耦合,其中來自客戶端的請求被傳遞到對象鏈以處理它們。然后鏈中的對象將自己決定誰將處理請求以及是否需要將請求發(fā)送到鏈中的下一個對象。
JDK中的責(zé)任鏈模式示例讓我們看一下JDK中責(zé)任鏈模式的例子,然后我們將繼續(xù)實(shí)現(xiàn)這種模式的真實(shí)例子。我們知道在try-catch塊代碼中我們可以有多個catch塊。這里每個catch塊都是處理該特定異常的處理器。
因此當(dāng)try塊中發(fā)生任何異常時,它會發(fā)送到第一個catch塊進(jìn)行處理。如果catch塊無法處理它,它會將請求轉(zhuǎn)發(fā)到鏈中的下一個對象,即下一個catch塊。如果即使最后一個catch塊也無法處理它,那么異常將被拋出鏈接到調(diào)用程序。
責(zé)任鏈設(shè)計(jì)模式示例責(zé)任鏈模式的一個很好的例子是ATM分配機(jī)器。用戶按照定義的貨幣賬單輸入要分配的金額和機(jī)器分配金額,例如50美元,20美元,10美元等。如果用戶輸入的數(shù)量不是10的倍數(shù),則會引發(fā)錯誤。我們將使用Chain of Responsibility模式來實(shí)現(xiàn)此解決方案。鏈將以與下圖相同的順序處理請求。
請注意,我們可以在單應(yīng)用程序中輕松實(shí)現(xiàn)此解決方案,但隨后復(fù)雜性將增加,解決方案將緊密耦合。因此,我們將創(chuàng)建一系列分配系統(tǒng),以分配50美元,20美元和10美元的賬單。
責(zé)任鏈設(shè)計(jì)模式 - 基類和接口我們可以創(chuàng)建一個類Currency來存儲分配和鏈實(shí)現(xiàn)使用的數(shù)量。
Currency.java
package com.journaldev.design.chainofresponsibility;public class Currency {private int amount;public Currency(int amt){this.amount=amt;}public int getAmount(){return this.amount;}}
基接口應(yīng)該有一個方法來定義鏈中的下一個處理器以及處理請求的方法。我們的ATM Dispense界面如下所示。
DispenseChain.java
package com.journaldev.design.chainofresponsibility;public interface DispenseChain {void setNextChain(DispenseChain nextChain);void dispense(Currency cur);}責(zé)任鏈模式 - 鏈實(shí)現(xiàn)
我們需要創(chuàng)建不同的處理器類來實(shí)現(xiàn)DispenseChain接口并提供分配方法的實(shí)現(xiàn)。由于我們正在開發(fā)我們的系統(tǒng)以使用三種類型的貨幣賬單--50美元,20美元和10美元,我們將創(chuàng)建三個具體實(shí)施。Dollar50Dispenser.java
package com.journaldev.design.chainofresponsibility;public class Dollar50Dispenser implements DispenseChain {private DispenseChain chain;@Overridepublic void setNextChain(DispenseChain nextChain) {this.chain=nextChain;}@Overridepublic void dispense(Currency cur) {if(cur.getAmount() >= 50){int num = cur.getAmount()/50;int remainder = cur.getAmount() % 50;System.out.println('Dispensing '+num+' 50$ note');if(remainder !=0) this.chain.dispense(new Currency(remainder));}else{this.chain.dispense(cur);}}}
Dollar20Dispenser.java
package com.journaldev.design.chainofresponsibility;public class Dollar20Dispenser implements DispenseChain{private DispenseChain chain;@Overridepublic void setNextChain(DispenseChain nextChain) {this.chain=nextChain;}@Overridepublic void dispense(Currency cur) {if(cur.getAmount() >= 20){int num = cur.getAmount()/20;int remainder = cur.getAmount() % 20;System.out.println('Dispensing '+num+' 20$ note');if(remainder !=0) this.chain.dispense(new Currency(remainder));}else{this.chain.dispense(cur);}}}
Dollar10Dispenser.java
package com.journaldev.design.chainofresponsibility;public class Dollar10Dispenser implements DispenseChain {private DispenseChain chain;@Overridepublic void setNextChain(DispenseChain nextChain) {this.chain=nextChain;}@Overridepublic void dispense(Currency cur) {if(cur.getAmount() >= 10){int num = cur.getAmount()/10;int remainder = cur.getAmount() % 10;System.out.println('Dispensing '+num+' 10$ note');if(remainder !=0) this.chain.dispense(new Currency(remainder));}else{this.chain.dispense(cur);}}}
這里要注意的重點(diǎn)是分配方法的實(shí)施。您會注意到每個實(shí)現(xiàn)都在嘗試處理請求,并且根據(jù)數(shù)量,它可能會處理部分或全部部分。如果其中一個鏈不能完全處理它,它會將請求發(fā)送到鏈中的下一個處理器以處理剩余的請求。如果處理器無法處理任何內(nèi)容,它只會將相同的請求轉(zhuǎn)發(fā)到下一個鏈。
責(zé)任鏈設(shè)計(jì)模式 - 創(chuàng)建鏈這是非常重要的一步,我們應(yīng)該仔細(xì)創(chuàng)建鏈,否則處理器可能根本沒有得到任何請求。例如,在我們的實(shí)現(xiàn)中,如果我們將第一個處理器鏈保持為Dollar10Dispenser然后Dollar20Dispenser,那么請求將永遠(yuǎn)不會被轉(zhuǎn)發(fā)到第二個處理器,并且鏈將變得無用。
這是我們的ATM Dispenser實(shí)現(xiàn),用于處理用戶請求的數(shù)量。
ATMDispenseChain.java
package com.journaldev.design.chainofresponsibility;import java.util.Scanner;public class ATMDispenseChain {private DispenseChain c1;public ATMDispenseChain() {// initialize the chainthis.c1 = new Dollar50Dispenser();DispenseChain c2 = new Dollar20Dispenser();DispenseChain c3 = new Dollar10Dispenser();// set the chain of responsibilityc1.setNextChain(c2);c2.setNextChain(c3);}public static void main(String[] args) {ATMDispenseChain atmDispenser = new ATMDispenseChain();while (true) {int amount = 0;System.out.println('Enter amount to dispense');Scanner input = new Scanner(System.in);amount = input.nextInt();if (amount % 10 != 0) {System.out.println('Amount should be in multiple of 10s.');return;}// process the requestatmDispenser.c1.dispense(new Currency(amount));}}}
當(dāng)我們運(yùn)行上面的應(yīng)用程序時,我們得到如下的輸出。
Enter amount to dispense
530
Dispensing 10 50$ note
Dispensing 1 20$ note
Dispensing 1 10$ note
Enter amount to dispense
100
Dispensing 2 50$ note
Enter amount to dispense
120
Dispensing 2 50$ note
Dispensing 1 20$ note
Enter amount to dispense
15
責(zé)任鏈設(shè)計(jì)模式類圖我們的ATM分配示例的責(zé)任鏈設(shè)計(jì)模式實(shí)現(xiàn)如下圖所示。
以上就是Java通俗易懂系列設(shè)計(jì)模式之責(zé)任鏈模式的詳細(xì)內(nèi)容,更多關(guān)于Java設(shè)計(jì)模式的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. jsp實(shí)現(xiàn)登錄界面2. AspNetCore&MassTransit Courier實(shí)現(xiàn)分布式事務(wù)的詳細(xì)過程3. 詳解瀏覽器的緩存機(jī)制4. ASP.NET泛型三之使用協(xié)變和逆變實(shí)現(xiàn)類型轉(zhuǎn)換5. jsp+servlet簡單實(shí)現(xiàn)上傳文件功能(保存目錄改進(jìn))6. XML基本概念XPath、XSLT與XQuery函數(shù)介紹7. .NET SkiaSharp 生成二維碼驗(yàn)證碼及指定區(qū)域截取方法實(shí)現(xiàn)8. JSP數(shù)據(jù)交互實(shí)現(xiàn)過程解析9. ASP基礎(chǔ)入門第八篇(ASP內(nèi)建對象Application和Session)10. 低版本IE正常運(yùn)行HTML5+CSS3網(wǎng)站的3種解決方案
