Java經(jīng)典設(shè)計(jì)模式之責(zé)任鏈模式原理與用法詳解
本文實(shí)例講述了Java經(jīng)典設(shè)計(jì)模式之責(zé)任鏈模式。分享給大家供大家參考,具體如下:
責(zé)任鏈模式:多個(gè)對(duì)象由其對(duì)象對(duì)應(yīng)下家的引用連成一條鏈,請(qǐng)求在這個(gè)鏈上傳遞,直到鏈上的某一個(gè)接收對(duì)象處理此請(qǐng)求。因?yàn)檎?qǐng)求的客戶端并不知道鏈上最終是誰來處理這個(gè)請(qǐng)求,使得系統(tǒng)可以在不影響客戶端的情況下動(dòng)態(tài)地重新組織和分配責(zé)任,從而避免了請(qǐng)求發(fā)送者與請(qǐng)求處理者之間的耦合。
責(zé)任鏈械中涉及到三種角色:
1,抽象處理者角色
2,具體處理者角色
3,請(qǐng)求發(fā)送者
小例子:假設(shè)去買房子,買房子就需要砍價(jià), 賣房的人職位不同,可以優(yōu)惠的價(jià)格也不同,不同職位就可以形成一個(gè)處理請(qǐng)求的鏈。我們暫定: * 基層銷售員,只能優(yōu)惠3% * 銷售經(jīng)理:可以優(yōu)惠5% * 銷售總監(jiān):可以優(yōu)惠8% * 老板(Boss):優(yōu)惠10%
直接上代碼:
/** * 抽象處理者(Handler)角色:處理請(qǐng)求的接口。如果需要,接口可以定義 出一個(gè)方法以設(shè)定和返回對(duì)下家的引用。 * 這個(gè)角色通常由一個(gè)Java抽象類或者Java接口實(shí)現(xiàn)。抽象方法handlePriceRequest()規(guī)范了子類處理請(qǐng)求的操作。 * @date 2015-12-24 上午11:26:56 */ public abstract class RoomRateHandler { protected RoomRateHandler mHandler; //直接由子類繼承,用于傳遞請(qǐng)求 public void setPriceHandler(RoomRateHandler mHandler){ this.mHandler=mHandler; } //處理具體問題:處理價(jià)格請(qǐng)求 public abstract void handlePriceRequest(float discount); /** * 設(shè)置請(qǐng)求處理鏈的層次關(guān)系 ,獲取處理請(qǐng)求的對(duì)象 * @description: * @date 2015-12-24 上午11:51:54 */ public static RoomRateHandler cretateHandler(){ RoomRateHandler salesMan=new SalesMan(); RoomRateHandler salesManager=new SalesManager(); RoomRateHandler saleDirector=new SalesDirector(); RoomRateHandler topManager=new TopManager(); salesMan.setPriceHandler(salesManager); salesManager.setPriceHandler(saleDirector); saleDirector.setPriceHandler(topManager); return salesMan; } }
具體處理者(SalesMan)角色
/** * 具體處理者(SalesMan)角色:具體處理者(SalesDirector)角色:具體處理者收到請(qǐng)求后,可以選擇處理請(qǐng)求,也可以將請(qǐng)求傳給下家(上級(jí))。 * 具體處理者都持有對(duì)鏈上下家(上級(jí))對(duì)象的引用,因此具體處理者把請(qǐng)求傳遞下去。 * @description: * @date 2015-12-24 上午11:29:16 */ public class SalesMan extends RoomRateHandler { @Override public void handlePriceRequest(float discount) { if(discount<=0.03){ System.out.format("%s批準(zhǔn)了:%.3f%n","業(yè)務(wù)員",discount); }else{ mHandler.handlePriceRequest(discount); } } }
具體處理者(SalesManager)角色
public class SalesManager extends RoomRateHandler { @Override public void handlePriceRequest(float discount) { if(discount<=0.08){ System.out.format("%s批準(zhǔn)了:%.3f%n","銷售經(jīng)理",discount); }else{ mHandler.handlePriceRequest(discount); } } }
具體處理者(SalesDirector )角色
public class SalesDirector extends RoomRateHandler { @Override public void handlePriceRequest(float discount) { if(discount<=0.05){ System.out.format("%s批準(zhǔn)了:%.3f%n","銷售總監(jiān)",discount); }else{ mHandler.handlePriceRequest(discount); } } }
具體處理者(TopManager)角色
/** * 具體處理者(TopManager)角色:因?yàn)楫?dāng)前 角色已經(jīng)處于鏈尾,所以是最終處理了。 * @description: * @author ldm * @date 2015-12-24 上午11:29:16 */ public class TopManager extends RoomRateHandler { @Override public void handlePriceRequest(float discount) { if (discount <= 0.1) { System.out.format("%s批準(zhǔn)了:%.3f%n", "老板", discount); } else { System.out.format("%s不同意:%.3f%n", "老板", discount); } } }
請(qǐng)求發(fā)送者
/** * 發(fā)出請(qǐng)求的客戶(模擬買房子的人) * @description: * @author ldm * @date 2015-12-24 上午11:35:54 */ public class Customer { private RoomRateHandler mHandler; public void setPriceHandler(RoomRateHandler mHandler) { this.mHandler = mHandler; } public void requestDiscount(float discount) { mHandler.handlePriceRequest(discount); } public static void main(String[] args) { Customer customer = new Customer(); customer.setPriceHandler(RoomRateHandler.cretateHandler());//獲取處理對(duì)象,站你面前的可能是老板,也可能是業(yè)務(wù)員... Random random = new Random(); for (int i = 0; i < 8; i++) {// 隨機(jī)構(gòu)造8個(gè)買房子的人 System.out.println(i + "---"); customer.requestDiscount(random.nextFloat()/10);//處理價(jià)格(談判) } } }
處理結(jié)果
如果要增加層級(jí)怎么辦呢?很簡(jiǎn)單,比如增加銷售主管SalesSupervisor,我們只需要新建一個(gè)類SalesSupervisor extends RoomRateHandler,實(shí)現(xiàn)處理方法handlePriceRequest(float discount);同時(shí)不要忘記在RoomRateHandler類中cretateHandler()中設(shè)置好對(duì)應(yīng)的層級(jí)鏈就可以啦。
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
解決Java處理HTTP請(qǐng)求超時(shí)的問題
這篇文章主要介紹了解決Java處理HTTP請(qǐng)求超時(shí)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03java中MultipartFile類型轉(zhuǎn)為File類型的4種方法
Spring提供了一個(gè)MultipartFile接口來處理文件上傳,但有時(shí)候我們需要將MultipartFile轉(zhuǎn)換為File來進(jìn)行一些特定的操作,比如保存文件到本地或者進(jìn)行文件的處理等,這篇文章主要給大家介紹了關(guān)于java中MultipartFile類型轉(zhuǎn)為File類型的4種方法,需要的朋友可以參考下2024-09-09java中PO、VO、BO、POJO、DAO、DTO、TO、QO、Bean、conn的理解
這篇文章主要介紹了java中PO、VO、BO、POJO、DAO、DTO、TO、QO、Bean、conn的理解,需要的朋友可以參考下2020-02-02實(shí)例分析Java中public static void main(String args[])是什么意思
這篇文章主要介紹了實(shí)例分析Java中public static void main(String args[])的意義,詳細(xì)分析了Java主函數(shù)main關(guān)鍵字聲明的具體含義和用法,需要的朋友可以參考下2015-12-12Java帶復(fù)選框的樹(Java CheckBox Tree)實(shí)現(xiàn)和應(yīng)用
這篇文章主要為大家詳細(xì)介紹了Java帶復(fù)選框的樹實(shí)現(xiàn)和應(yīng)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11多模塊項(xiàng)目引入SpringSecurity后一直報(bào)404的解決方案
這篇文章主要介紹了多模塊項(xiàng)目引入SpringSecurity后一直報(bào)404的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06Kotlin-Coroutines中的async與await異步協(xié)程管理
這篇文章主要為大家介紹了Kotlin-Coroutines中的async與await異步協(xié)程管理,提升程序性能解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10