Java使用責(zé)任鏈模式處理學(xué)生請(qǐng)假問題詳解
本文實(shí)例講述了Java使用責(zé)任鏈模式處理學(xué)生請(qǐng)假問題。分享給大家供大家參考,具體如下:
一. 模式定義
在責(zé)任鏈模式中,很多對(duì)象由每一個(gè)對(duì)象對(duì)其下家的引用而連接起來,形成一條鏈??蛻舳藨?yīng)用請(qǐng)求在這個(gè)鏈上進(jìn)行傳遞,直到鏈上的某一個(gè)對(duì)象決定處理此請(qǐng)求。發(fā)出這個(gè)請(qǐng)求的客戶端并不知道鏈上的哪個(gè)對(duì)象最終處理這個(gè)請(qǐng)求,這使系統(tǒng)可以在不影響客戶端的情況下動(dòng)態(tài)地重新組織鏈和分配責(zé)任。
(1)抽象處理者角色:定義出一個(gè)處理請(qǐng)求的接口。如果需要,接口可以定義出一個(gè)方法,以設(shè)定和返回下家的引用。這個(gè)角色通常由一個(gè)Java抽象類或Java接口實(shí)現(xiàn)。
(2)具體處理角色:具體處理者接到請(qǐng)求后,可以選擇將請(qǐng)求處理掉,或者將請(qǐng)求傳給下家。
二. 模式舉例
1 模式分析
我們借用學(xué)生請(qǐng)假來說明這一模式
2 責(zé)任鏈模式靜態(tài)類圖
3 代碼示例
3.1學(xué)生接口一IStudent
package com.demo.chain.message; /** * 學(xué)生接口 * * @author * */ public interface IStudent { /** * 獲得學(xué)生病情狀態(tài) * * 0:小事(班長(zhǎng)就可以處理) * * 1:班長(zhǎng)處理不了 老師能處理的事 * * 2:老師處理不了 校長(zhǎng)能處理的事 * * */ public int getState(); /** * 獲得學(xué)生請(qǐng)假消息 * * @return */ public String getRequestMessage(); }
3.2學(xué)生實(shí)現(xiàn)一Student
package com.demo.chain.message; /** * 學(xué)生實(shí)現(xiàn)類 * * @author * */ public class Student implements IStudent { // 病情的大小狀態(tài) private int state = -1; // 請(qǐng)假消息 private final String message; public Student(int state, String message) { this.state = state; this.message = message; } /** * 獲得學(xué)生請(qǐng)假狀態(tài) * * 0:小事(班長(zhǎng)就可以處理) * * 1:班長(zhǎng)處理不了 老師能處理的事 * * 2:老師處理不了 校長(zhǎng)能處理的事 * * */ public int getState() { return this.state; } /** * 獲得學(xué)生請(qǐng)假消息 * * @return */ public String getRequestMessage() { return this.message; } }
3.3抽象處理接口一IHandler
package com.demo.chain.handle; import com.demo.chain.message.IStudent; /** * 抽象處理者接口 * * @author * */ public interface IHandler { // 處理請(qǐng)求 public void handleRequest(IStudent student); // 設(shè)置下一個(gè)處理者 public void setHandler(IHandler handler); }
3.4抽象處理者一AbstractHandler
package com.demo.chain.handle; import com.demo.chain.message.IStudent; /** * 抽象處理者 * * @author * */ public abstract class AbstractHandler implements IHandler { // 下一個(gè)處理者 private IHandler handler; // 請(qǐng)假級(jí)別 private int state = -1; // 構(gòu)造方法 設(shè)置級(jí)別 public AbstractHandler(int state) { this.state = state; } // 處理請(qǐng)求 交由子類負(fù)責(zé)進(jìn)行具體的處理 public abstract void process(IStudent student); // 處理請(qǐng)求 public void handleRequest(IStudent student) { // 如果學(xué)生對(duì)象存在 if (student != null) { if (this.state == student.getState()) { // 如果請(qǐng)假級(jí)別和當(dāng)前一致 則當(dāng)前對(duì)象進(jìn)行處理 this.process(student); } else { if (this.handler != null) { System.out.println("請(qǐng)求上級(jí)領(lǐng)導(dǎo)批復(fù)!"); // 如果當(dāng)前對(duì)象處理不了 則交給下一個(gè)處理者進(jìn)行處理 this.handler.handleRequest(student); } } } } // 設(shè)置下一個(gè)處理者 public void setHandler(IHandler handler) { this.handler = handler; } }
3.5班長(zhǎng)一SquadLeaderHandler
package com.demo.chain.handle; import com.demo.chain.message.IStudent; /** * 抽象處理者 * * @author * */ public abstract class AbstractHandler implements IHandler { // 下一個(gè)處理者 private IHandler handler; // 請(qǐng)假級(jí)別 private int state = -1; // 構(gòu)造方法 設(shè)置級(jí)別 public AbstractHandler(int state) { this.state = state; } // 處理請(qǐng)求 交由子類負(fù)責(zé)進(jìn)行具體的處理 public abstract void process(IStudent student); // 處理請(qǐng)求 public void handleRequest(IStudent student) { // 如果學(xué)生對(duì)象存在 if (student != null) { if (this.state == student.getState()) { // 如果請(qǐng)假級(jí)別和當(dāng)前一致 則當(dāng)前對(duì)象進(jìn)行處理 this.process(student); } else { if (this.handler != null) { System.out.println("請(qǐng)求上級(jí)領(lǐng)導(dǎo)批復(fù)!"); // 如果當(dāng)前對(duì)象處理不了 則交給下一個(gè)處理者進(jìn)行處理 this.handler.handleRequest(student); } } } } // 設(shè)置下一個(gè)處理者 public void setHandler(IHandler handler) { this.handler = handler; } }
3.6老師一TeacherHandler
package com.demo.chain.impl; import com.demo.chain.handle.AbstractHandler; import com.demo.chain.message.IStudent; /** * 老師處理者 * * @author * */ public class TeacherHandler extends AbstractHandler { public TeacherHandler() { super(1); } // 子類具體處理請(qǐng)求 @Override public void process(IStudent student) { System.out.println("老師 批復(fù):" + student.getRequestMessage()); } }
3.7校長(zhǎng)一SchoolMasterHandler
package com.demo.chain.impl; import com.demo.chain.handle.AbstractHandler; import com.demo.chain.message.IStudent; /** * 校長(zhǎng)處理者 * * @author * */ public class SchoolMasterHandler extends AbstractHandler { public SchoolMasterHandler() { super(2); } // 子類具體處理請(qǐng)求 @Override public void process(IStudent student) { System.out.println("校長(zhǎng) 批復(fù):" + student.getRequestMessage()); } }
3.8外觀類一ProcessHandler
package com.demo.chain.process; import com.demo.chain.handle.IHandler; import com.demo.chain.impl.SchoolMasterHandler; import com.demo.chain.impl.SquadLeaderHandler; import com.demo.chain.impl.TeacherHandler; import com.demo.chain.message.IStudent; /** * 設(shè)置責(zé)任鏈關(guān)聯(lián) * * @author * */ public class ProcessHandler { // 班長(zhǎng)處理者 private final IHandler sqmshandler; // 老師處理者 private final IHandler techhandler; // 校長(zhǎng)處理者 private final IHandler scmshandler; // 單例模式 private static ProcessHandler processHandler = new ProcessHandler(); /** * 構(gòu)造方法建立請(qǐng)假處理責(zé)任鏈 */ private ProcessHandler() { // 創(chuàng)建處理對(duì)象 // 班長(zhǎng) this.sqmshandler = new SquadLeaderHandler(); // 老師 this.techhandler = new TeacherHandler(); // 校長(zhǎng) this.scmshandler = new SchoolMasterHandler(); /** * 建立責(zé)任鏈 */ // 設(shè)置班長(zhǎng)的下一個(gè)處理者:老師 this.sqmshandler.setHandler(this.techhandler); // 設(shè)置老師的下一個(gè)處理者:校長(zhǎng) this.techhandler.setHandler(this.scmshandler); } /** * 獲得單例對(duì)象實(shí)例 * * @return */ public static ProcessHandler getInstance() { return processHandler; } /** * 發(fā)送請(qǐng)假請(qǐng)求 * * @param message */ public void sendMessage(IStudent student) { // 發(fā)送給第一個(gè)處理者:班長(zhǎng) 處理 this.sqmshandler.handleRequest(student); } }
3.9客戶端一Client
package com.demo; import java.util.Random; import com.demo.chain.message.IStudent; import com.demo.chain.message.Student; import com.demo.chain.process.ProcessHandler; /** * 主應(yīng)用程序 * * @author * */ public class Client { /** * @param args */ public static void main(String[] args) { // 獲得外觀對(duì)象 ProcessHandler processHandler = ProcessHandler.getInstance(); // 創(chuàng)建隨機(jī)數(shù)對(duì)象 用來隨機(jī)產(chǎn)生學(xué)生對(duì)象 Random random = new Random(); for (int i = 0; i < 3; i++) { // 獲得隨機(jī)數(shù) int radom = random.nextInt(3); IStudent student = new Student(radom, "學(xué)生" + i + "生病了,要請(qǐng)假!"); System.out.println("#################################"); // 處理消息 processHandler.sendMessage(student); System.out.println("#################################\n"); } } }
4 運(yùn)行結(jié)果
#################################
請(qǐng)求上級(jí)領(lǐng)導(dǎo)批復(fù)!
請(qǐng)求上級(jí)領(lǐng)導(dǎo)批復(fù)!
校長(zhǎng) 批復(fù):學(xué)生0生病了,要請(qǐng)假!
#################################
#################################
請(qǐng)求上級(jí)領(lǐng)導(dǎo)批復(fù)!
請(qǐng)求上級(jí)領(lǐng)導(dǎo)批復(fù)!
校長(zhǎng) 批復(fù):學(xué)生1生病了,要請(qǐng)假!
#################################
#################################
班長(zhǎng) 批復(fù):學(xué)生2生病了,要請(qǐng)假!
#################################
三. 該模式設(shè)計(jì)原則
1"開-閉"原則
2單一職責(zé)原則
四. 使用場(chǎng)合
(1)有多個(gè)對(duì)象處理同一請(qǐng)求,具體由哪一個(gè)來處理還不確定,只有在運(yùn)行時(shí)才確定哪個(gè)對(duì)象處理的情況。
(2)消息具有多個(gè)接收者,而接收對(duì)象又是不明確的情況。只需要向其中的一個(gè)對(duì)象發(fā)出消息,由其內(nèi)部具體處理。
(3)同一消息的多個(gè)處理對(duì)象可能會(huì)動(dòng)態(tài)增加或減少,需要?jiǎng)討B(tài)地指定的情況。
五. 責(zé)任鏈模式靜態(tài)類圖
更多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)文章
swing jtextArea滾動(dòng)條和文字縮放效果
這篇文章主要為大家詳細(xì)介紹了swing jtextArea滾動(dòng)條和文字縮放效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12基于SpringBoot實(shí)現(xiàn)大文件分塊上傳功能
這篇文章主要介紹了基于SpringBoot實(shí)現(xiàn)大文件分塊上傳功能,實(shí)現(xiàn)原理其實(shí)很簡(jiǎn)單,核心就是客戶端把大文件按照一定規(guī)則進(jìn)行拆分,比如20MB為一個(gè)小塊,分解成一個(gè)一個(gè)的文件塊,然后把這些文件塊單獨(dú)上傳到服務(wù)端,需要的朋友可以參考下2024-09-09Mybatis不支持batchInsertOrUpdate返顯id問題
這篇文章主要介紹了Mybatis不支持batchInsertOrUpdate返顯id問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05Springboot項(xiàng)目引入druid安裝部署使用教程
這篇文章主要介紹了Springboot項(xiàng)目引入druid安裝部署使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01Spring boot2基于Mybatis實(shí)現(xiàn)多表關(guān)聯(lián)查詢
這篇文章主要介紹了Spring boot2基于Mybatis實(shí)現(xiàn)多表關(guān)聯(lián)查詢,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04