Java使用責(zé)任鏈模式處理學(xué)生請(qǐng)假問(wèn)題詳解
本文實(shí)例講述了Java使用責(zé)任鏈模式處理學(xué)生請(qǐng)假問(wèn)題。分享給大家供大家參考,具體如下:
一. 模式定義
在責(zé)任鏈模式中,很多對(duì)象由每一個(gè)對(duì)象對(duì)其下家的引用而連接起來(lái),形成一條鏈??蛻?hù)端應(yīng)用請(qǐng)求在這個(gè)鏈上進(jìn)行傳遞,直到鏈上的某一個(gè)對(duì)象決定處理此請(qǐng)求。發(fā)出這個(gè)請(qǐng)求的客戶(hù)端并不知道鏈上的哪個(gè)對(duì)象最終處理這個(gè)請(qǐng)求,這使系統(tǒng)可以在不影響客戶(hù)端的情況下動(dòng)態(tài)地重新組織鏈和分配責(zé)任。
(1)抽象處理者角色:定義出一個(gè)處理請(qǐng)求的接口。如果需要,接口可以定義出一個(gè)方法,以設(shè)定和返回下家的引用。這個(gè)角色通常由一個(gè)Java抽象類(lèi)或Java接口實(shí)現(xiàn)。
(2)具體處理角色:具體處理者接到請(qǐng)求后,可以選擇將請(qǐng)求處理掉,或者將請(qǐng)求傳給下家。
二. 模式舉例
1 模式分析
我們借用學(xué)生請(qǐng)假來(lái)說(shuō)明這一模式

2 責(zé)任鏈模式靜態(tài)類(lè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)類(lèi)
*
* @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)求 交由子類(lèi)負(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)求 交由子類(lèi)負(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);
}
// 子類(lèi)具體處理請(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);
}
// 子類(lèi)具體處理請(qǐng)求
@Override
public void process(IStudent student) {
System.out.println("校長(zhǎng) 批復(fù):" + student.getRequestMessage());
}
}
3.8外觀類(lèi)一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客戶(hù)端一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ì)象 用來(lái)隨機(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"開(kāi)-閉"原則
2單一職責(zé)原則
四. 使用場(chǎng)合
(1)有多個(gè)對(duì)象處理同一請(qǐng)求,具體由哪一個(gè)來(lái)處理還不確定,只有在運(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)類(lèi)圖

更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
springboot?maven?打包插件介紹及注意事項(xiàng)說(shuō)明
這篇文章主要介紹了springboot?maven?打包插件介紹及注意事項(xiàng)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
java equals和=,==的區(qū)別詳細(xì)介紹
這篇文章主要介紹了java equals和=,==的區(qū)別,學(xué)習(xí)Java的朋友對(duì)equals 和== 這個(gè)概念開(kāi)始使用的時(shí)候會(huì)有疑問(wèn),很難辨別如何正確使用,這里幫大家詳細(xì)講解該知識(shí)點(diǎn),希望大家能掌握,有需要的小伙伴可以參考下2016-10-10
解決SpringBoot掃描不到公共類(lèi)的實(shí)體問(wèn)題
這篇文章主要介紹了解決SpringBoot掃描不到公共類(lèi)的實(shí)體問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Java 可視化垃圾回收_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Ben Evans是一名資深培訓(xùn)師兼顧問(wèn),他在演講可視化垃圾回收中從基礎(chǔ)談起討論了垃圾回收。以下是對(duì)其演講的簡(jiǎn)短總結(jié)。感興趣的朋友一起學(xué)習(xí)吧2017-05-05
使用jekins自動(dòng)構(gòu)建部署java maven項(xiàng)目的方法步驟
這篇文章主要介紹了使用jekins自動(dòng)構(gòu)建部署java maven項(xiàng)目的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
SpringBoot 設(shè)置傳入?yún)?shù)非必要的操作
這篇文章主要介紹了SpringBoot 設(shè)置傳入?yún)?shù)非必要的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
Mybatis之a(chǎn)ssociation和collection用法
這篇文章主要介紹了Mybatis之a(chǎn)ssociation和collection用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Java并發(fā)之synchronized實(shí)現(xiàn)原理深入理解
這篇文章主要介紹了Java中synchronized實(shí)現(xiàn)原理詳解,涉及synchronized實(shí)現(xiàn)同步的基礎(chǔ),Java對(duì)象頭,Monitor,Mark Word,鎖優(yōu)化,自旋鎖等相關(guān)內(nèi)容,具有一定借鑒價(jià)值,需要的朋友可以參考下2021-08-08

