責(zé)任鏈模式
定義
使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免了請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,知道有對(duì)象處理它為止。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
能將請(qǐng)求和處理分開。請(qǐng)求者可以不用知道是誰(shuí)處理的,處理者可以不用知道請(qǐng)求的全貌,兩者解耦提高系統(tǒng)的靈活性
缺點(diǎn)
- 性能問題,每個(gè)請(qǐng)求都是從鏈頭遍歷到鏈尾,尤其是鏈較長(zhǎng)的時(shí)候,會(huì)有性能方面的影響。
- 調(diào)試不方便,由于采用了類似遞歸的方式(本實(shí)驗(yàn)用的是隊(duì)列的遍歷),調(diào)試的時(shí)候會(huì)比較復(fù)雜。
實(shí)驗(yàn)小結(jié)
- 即一個(gè)任務(wù)到來(lái)時(shí),進(jìn)入責(zé)任鏈,從頭開始遍歷責(zé)任人,不是則依次往下尋找,直到找到負(fù)責(zé)該任務(wù)的責(zé)任人(可能無(wú)人負(fù)責(zé))
- 將責(zé)任鏈節(jié)點(diǎn)依次加入隊(duì)列就能build()出責(zé)任鏈關(guān)系。
代碼模擬場(chǎng)景
項(xiàng)目進(jìn)入測(cè)試階段,項(xiàng)目組出現(xiàn)問題,依次尋找測(cè)試、開發(fā)、產(chǎn)品經(jīng)理尋求幫助。
責(zé)任鏈模式
UML圖
責(zé)任鏈節(jié)點(diǎn)抽象、實(shí)現(xiàn)類
public abstract class AbstractHandler {
/**
* 測(cè)試處理等級(jí)
*/
public final static int TEST_LEVEL_REQUEST = 1;
/**
* 開發(fā)處理等級(jí)
*/
public final static int DEVELOPER_LEVEL_REQUEST = 2;
/**
* 產(chǎn)品經(jīng)理處理等級(jí)
*/
public final static int PRODUCT_MANAGER_LEVEL_REQUEST = 3;
/**
* 能處理的級(jí)別
*/
private final int level;
/**
* 責(zé)任傳遞,下個(gè)責(zé)任人是誰(shuí)
*/
private AbstractHandler nextHandler;
/**
* 每個(gè)責(zé)任節(jié)點(diǎn)都要說(shuō)明下自己能處理哪些需求
*
* @param level 處理等級(jí)
*/
public AbstractHandler(int level) {
this.level = level;
}
/**
* 處理項(xiàng)目的要求
*
* @param project 項(xiàng)目需要
*/
public final void handleMessage(IProject project) {
if (project.getType() == this.level) {
this.response(project);
} else {
// 后續(xù)有環(huán)節(jié)則繼續(xù)推進(jìn)請(qǐng)求
if (this.nextHandler != null) {
this.nextHandler.handleMessage(project);
} else {
System.out.println("已無(wú)流程批示,不同意");
}
}
}
/**
* 傳遞給下個(gè)處理人
*
* @param handler 下個(gè)處理人
*/
public void setNext(AbstractHandler handler) {
this.nextHandler = handler;
}
/**
* 處理人的回應(yīng)
*
* @param project 項(xiàng)目對(duì)象
*/
protected abstract void response(IProject project);
}
/**
* @author Evad.Wu
* @Description 測(cè)試工程師
* @date 2023-07-10
*/
public class TestEngineer extends AbstractHandler {
/**
* 每個(gè)責(zé)任節(jié)點(diǎn)都要說(shuō)明下自己能處理哪些需求
*/
public TestEngineer() {
super(AbstractHandler.TEST_LEVEL_REQUEST);
}
@Override
protected void response(IProject project) {
System.out.println("項(xiàng)目組向測(cè)試人員咨詢");
System.out.println(project.getRequest());
System.out.println("測(cè)試人員的答復(fù)是:找我就對(duì)了");
}
}
/**
* @author Evad.Wu
* @Description 開發(fā)工程師
* @date 2023-07-10
*/
public class DevelopmentEngineer extends AbstractHandler {
/**
* 每個(gè)責(zé)任節(jié)點(diǎn)都要說(shuō)明下自己能處理哪些需求
*/
public DevelopmentEngineer() {
super(AbstractHandler.DEVELOPER_LEVEL_REQUEST);
}
@Override
protected void response(IProject project) {
System.out.println("項(xiàng)目組向開發(fā)人員咨詢");
System.out.println(project.getRequest());
System.out.println("開發(fā)人員的答復(fù)是:找我就對(duì)了");
}
}
/**
* @author Evad.Wu
* @Description 產(chǎn)品經(jīng)理
* @date 2023-07-10
*/
public class ProductManager extends AbstractHandler {
/**
* 每個(gè)責(zé)任節(jié)點(diǎn)都要說(shuō)明下自己能處理哪些需求
*/
public ProductManager() {
super(AbstractHandler.PRODUCT_MANAGER_LEVEL_REQUEST);
}
@Override
protected void response(IProject project) {
System.out.println("項(xiàng)目組向產(chǎn)品經(jīng)理咨詢");
System.out.println(project.getRequest());
System.out.println("產(chǎn)品經(jīng)理的答復(fù)是:找我就對(duì)了");
}
}
項(xiàng)目組抽象、實(shí)現(xiàn)類
public interface IProject {
/**
* 獲取咨詢問題的類型
*
* @return 類型編號(hào)
*/
int getType();
/**
* 獲取咨詢的內(nèi)容
*
* @return 咨詢的內(nèi)容
*/
String getRequest();
}
public class ProjectImpl implements IProject {
/**
* 問題類型
* 1-測(cè)試處理 2-開發(fā)處理 3-產(chǎn)品處理
*/
private final int type;
/**
* 本次處理的請(qǐng)求
*/
private String request;
public ProjectImpl(int type, String request) {
this.type = type;
this.request = request;
switch (this.type) {
case 1 -> this.request += "測(cè)試方面的咨詢";
case 2 -> this.request += "開發(fā)方面的咨詢";
case 3 -> this.request += "產(chǎn)品方面的咨詢";
default -> this.request += "沒有人對(duì)應(yīng)的人員可以處理";
}
}
/**
* 獲取咨詢問題的類型
*
* @return 類型編號(hào)
*/
public int getType() {
return type;
}
/**
* 獲取咨詢的內(nèi)容
*
* @return 咨詢的內(nèi)容
*/
public String getRequest() {
return request;
}
}
責(zé)任鏈
負(fù)責(zé)將節(jié)點(diǎn)串聯(lián)起來(lái)
public class Chain<T extends AbstractHandler> {
// 定義三個(gè)咨詢對(duì)象
private AbstractHandler peek;
public Chain(Queue<T> sequence) {
if (!sequence.isEmpty()) {
T peek = sequence.peek();
this.peek = peek;
sequence.poll();
for (T current : sequence) {
peek.setNext(current);
peek = current;
}
}
}
public AbstractHandler build() {
return peek;
}
}
入口類
public class ResponsibilityChainMain {
public static void main(String[] args) {
List<IProject> projectList = new ArrayList<>();
projectList.add(new ProjectImpl(1, "項(xiàng)目出問題,需要人員支持..."));
projectList.add(new ProjectImpl(2, "項(xiàng)目出問題,需要人員支持..."));
projectList.add(new ProjectImpl(3, "項(xiàng)目出問題,需要人員支持..."));
projectList.add(new ProjectImpl(4, "項(xiàng)目出問題,需要人員支持..."));
Queue<AbstractHandler> sequence = new LinkedList<>();
// 咨詢的順序是:測(cè)試、開發(fā)、產(chǎn)品經(jīng)理
sequence.add(new TestEngineer());
sequence.add(new DevelopmentEngineer());
sequence.add(new ProductManager());
AbstractHandler handler = new Chain<>(sequence).build();
for (IProject project : projectList) {
handler.handleMessage(project);
System.out.println();
}
}
}
結(jié)果
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-558015.html
參考書籍
秦小波《設(shè)計(jì)模式之禪》文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-558015.html
到了這里,關(guān)于設(shè)計(jì)模式——責(zé)任鏈模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!