1. 說(shuō)明
責(zé)任鏈模式是一種行為設(shè)計(jì)模式,它允許你創(chuàng)建一個(gè)對(duì)象鏈,每個(gè)對(duì)象都包含了請(qǐng)求的一部分處理邏輯,并且請(qǐng)求按照鏈的順序依次傳遞,直到有一個(gè)對(duì)象處理它為止。責(zé)任鏈模式通常用于將一個(gè)請(qǐng)求從發(fā)送者傳遞給多個(gè)接收者,直到有一個(gè)接收者處理請(qǐng)求為止。
責(zé)任鏈模式的核心概念包括以下要點(diǎn):
- 處理者對(duì)象鏈: 責(zé)任鏈由多個(gè)處理者(處理對(duì)象)組成,每個(gè)處理者都知道下一個(gè)處理者。請(qǐng)求從鏈的起點(diǎn)進(jìn)入,然后依次沿著鏈傳遞,直到某個(gè)處理者能夠處理請(qǐng)求。
- 請(qǐng)求處理: 每個(gè)處理者都有一個(gè)處理請(qǐng)求的方法,當(dāng)它無(wú)法處理請(qǐng)求時(shí),會(huì)將請(qǐng)求傳遞給鏈中的下一個(gè)處理者。處理者可以決定是否處理請(qǐng)求,也可以將請(qǐng)求傳遞給下一個(gè)處理者。
- 動(dòng)態(tài)性: 責(zé)任鏈模式允許你在運(yùn)行時(shí)動(dòng)態(tài)添加或刪除處理者,因此可以靈活地調(diào)整處理邏輯。
- 避免顯式引用: 請(qǐng)求發(fā)送者不需要知道鏈中的哪個(gè)處理者將處理請(qǐng)求,它只需要將請(qǐng)求發(fā)送到鏈的起點(diǎn)。
責(zé)任鏈模式通常用于以下情況:
- 當(dāng)有多個(gè)對(duì)象可以處理請(qǐng)求,但請(qǐng)求的處理者在運(yùn)行時(shí)確定。
- 當(dāng)請(qǐng)求的發(fā)送者和接收者之間需要解耦,以便更容易地添加或修改處理者。
- 當(dāng)需要按照一定順序處理請(qǐng)求。
一個(gè)常見(jiàn)的例子是審批流程,其中不同級(jí)別的審批者依次審批請(qǐng)求,直到最終決策被達(dá)成。責(zé)任鏈模式可以有效地支持這種工作流程。
2. 使用的場(chǎng)景
責(zé)任鏈模式通常用于以下情況和場(chǎng)景:
3. 請(qǐng)求的處理者不確定: 當(dāng)請(qǐng)求的處理者在運(yùn)行時(shí)才能確定,并且需要?jiǎng)討B(tài)配置或修改處理邏輯時(shí),責(zé)任鏈模式非常有用。這使得可以輕松地添加、移除或重新排序處理者,而無(wú)需更改請(qǐng)求的發(fā)送者。
4. 避免發(fā)送者和接收者之間的直接耦合: 使用責(zé)任鏈模式,請(qǐng)求的發(fā)送者不需要知道具體哪個(gè)對(duì)象將處理請(qǐng)求,只需要將請(qǐng)求發(fā)送到鏈的起點(diǎn)。這可以降低系統(tǒng)中不同組件之間的耦合度。
5. 按順序處理請(qǐng)求: 當(dāng)請(qǐng)求需要按照一定順序依次處理時(shí),責(zé)任鏈模式非常適合。例如,審批流程中,不同級(jí)別的審批者依次處理請(qǐng)求。
6. 處理多個(gè)請(qǐng)求對(duì)象: 當(dāng)系統(tǒng)中有多個(gè)請(qǐng)求對(duì)象,而每個(gè)請(qǐng)求可能需要被不同的處理者處理時(shí),責(zé)任鏈模式可以有效地管理和處理這些請(qǐng)求。
7. 解耦復(fù)雜的處理邏輯: 當(dāng)處理邏輯復(fù)雜且難以單獨(dú)管理時(shí),可以將處理邏輯分解成多個(gè)處理者,每個(gè)處理者負(fù)責(zé)處理一部分邏輯,從而簡(jiǎn)化系統(tǒng)的設(shè)計(jì)和維護(hù)。
8. 錯(cuò)誤處理和日志記錄: 在錯(cuò)誤處理和日志記錄方面,責(zé)任鏈模式可以用于捕獲異常、記錄日志或執(zhí)行特定的錯(cuò)誤處理邏輯。
9. 權(quán)限驗(yàn)證: 在應(yīng)用程序中,可以使用責(zé)任鏈模式來(lái)處理用戶(hù)權(quán)限驗(yàn)證。不同的處理者可以檢查用戶(hù)是否具有執(zhí)行某個(gè)操作的權(quán)限。
總之,責(zé)任鏈模式在需要將請(qǐng)求從發(fā)送者傳遞給多個(gè)接收者,并且能夠在運(yùn)行時(shí)動(dòng)態(tài)配置處理邏輯的情況下非常有用。這種模式提供了一種可擴(kuò)展和靈活的方法來(lái)管理復(fù)雜的請(qǐng)求處理流程。
3. 應(yīng)用例子
以下是一個(gè)使用 Python 實(shí)現(xiàn)的簡(jiǎn)單責(zé)任鏈模式示例,模擬請(qǐng)求處理鏈,請(qǐng)求從一個(gè)處理者傳遞到另一個(gè)處理者,直到有一個(gè)處理它為止。這個(gè)示例將處理請(qǐng)求的問(wèn)題按照不同的難度級(jí)別分配給不同的處理者。
# 抽象處理者類(lèi)
class Handler:
def __init__(self, successor=None):
self.successor = successor
def handle_request(self, request):
if self.successor:
self.successor.handle_request(request)
# 具體處理者類(lèi)
class EasyHandler(Handler):
def handle_request(self, request):
if request <= 10:
print(f"EasyHandler: Handling request {request}")
else:
super().handle_request(request)
class MediumHandler(Handler):
def handle_request(self, request):
if 10 < request <= 50:
print(f"MediumHandler: Handling request {request}")
else:
super().handle_request(request)
class HardHandler(Handler):
def handle_request(self, request):
if request > 50:
print(f"HardHandler: Handling request {request}")
# 客戶(hù)端代碼
if __name__ == "__main__":
# 創(chuàng)建處理者鏈
hard_handler = HardHandler()
medium_handler = MediumHandler(hard_handler)
easy_handler = EasyHandler(medium_handler)
# 發(fā)送不同難度級(jí)別的請(qǐng)求
requests = [5, 15, 60]
for request in requests:
easy_handler.handle_request(request)
4. 實(shí)現(xiàn)要素
責(zé)任鏈模式的實(shí)現(xiàn)要素包括以下關(guān)鍵角色:
- 抽象處理者(Handler):定義處理請(qǐng)求的接口或抽象類(lèi)。通常包含一個(gè)指向下一個(gè)處理者的引用(后繼者),并且提供一個(gè)處理請(qǐng)求的方法(handleRequest)。這個(gè)角色可以是抽象類(lèi)或接口。
- 具體處理者(ConcreteHandler):實(shí)現(xiàn)抽象處理者接口,負(fù)責(zé)處理具體的請(qǐng)求。如果自己無(wú)法處理請(qǐng)求,可以將請(qǐng)求傳遞給下一個(gè)處理者。每個(gè)具體處理者通常只能處理一類(lèi)請(qǐng)求。
- 客戶(hù)端(Client):創(chuàng)建請(qǐng)求并將其發(fā)送到處理者鏈的起點(diǎn)??蛻?hù)端通常不需要知道鏈中的具體處理者,只需要將請(qǐng)求發(fā)送給第一個(gè)處理者。
5. Java/golang/javascrip/C++ 等語(yǔ)言實(shí)現(xiàn)方式
5.1 Java實(shí)現(xiàn)
上述例子用Java語(yǔ)言實(shí)現(xiàn)示例如下:
// 抽象處理者接口
interface Handler {
void handleRequest(int request);
void setSuccessor(Handler successor);
}
// 具體處理者類(lèi)
class EasyHandler implements Handler {
private Handler successor;
@Override
public void handleRequest(int request) {
if (request <= 10) {
System.out.println("EasyHandler: Handling request " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
@Override
public void setSuccessor(Handler successor) {
this.successor = successor;
}
}
class MediumHandler implements Handler {
private Handler successor;
@Override
public void handleRequest(int request) {
if (request > 10 && request <= 50) {
System.out.println("MediumHandler: Handling request " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
@Override
public void setSuccessor(Handler successor) {
this.successor = successor;
}
}
class HardHandler implements Handler {
@Override
public void handleRequest(int request) {
if (request > 50) {
System.out.println("HardHandler: Handling request " + request);
}
}
@Override
public void setSuccessor(Handler successor) {
// 最后一個(gè)處理者,不設(shè)置后繼者
}
}
// 客戶(hù)端代碼
public class Main {
public static void main(String[] args) {
// 創(chuàng)建處理者鏈
Handler hardHandler = new HardHandler();
Handler mediumHandler = new MediumHandler();
Handler easyHandler = new EasyHandler();
// 設(shè)置處理者的后繼者
easyHandler.setSuccessor(mediumHandler);
mediumHandler.setSuccessor(hardHandler);
// 發(fā)送不同難度級(jí)別的請(qǐng)求
int[] requests = {5, 15, 60};
for (int request : requests) {
easyHandler.handleRequest(request);
}
}
}
在這個(gè) Java 示例中,我們定義了一個(gè) Handler 接口和三個(gè)具體的處理者類(lèi),然后在客戶(hù)端代碼中創(chuàng)建了處理者鏈,按順序?qū)⒄?qǐng)求發(fā)送給鏈的起點(diǎn) easyHandler。不同難度級(jí)別的請(qǐng)求將由不同的處理者處理,或者傳遞給下一個(gè)處理者。
5.2 Golang實(shí)現(xiàn)
上述例子用golang實(shí)現(xiàn)示例如下:
package main
import (
"fmt"
)
// Handler 接口定義了處理請(qǐng)求的方法和設(shè)置后繼者的方法
type Handler interface {
HandleRequest(request int)
SetSuccessor(successor Handler)
}
// EasyHandler 是具體處理者,處理難度級(jí)別低的請(qǐng)求
type EasyHandler struct {
successor Handler
}
func (e *EasyHandler) HandleRequest(request int) {
if request <= 10 {
fmt.Printf("EasyHandler: Handling request %d\n", request)
} else if e.successor != nil {
e.successor.HandleRequest(request)
}
}
func (e *EasyHandler) SetSuccessor(successor Handler) {
e.successor = successor
}
// MediumHandler 是具體處理者,處理難度級(jí)別中等的請(qǐng)求
type MediumHandler struct {
successor Handler
}
func (m *MediumHandler) HandleRequest(request int) {
if request > 10 && request <= 50 {
fmt.Printf("MediumHandler: Handling request %d\n", request)
} else if m.successor != nil {
m.successor.HandleRequest(request)
}
}
func (m *MediumHandler) SetSuccessor(successor Handler) {
m.successor = successor
}
// HardHandler 是具體處理者,處理難度級(jí)別高的請(qǐng)求
type HardHandler struct{}
func (h *HardHandler) HandleRequest(request int) {
if request > 50 {
fmt.Printf("HardHandler: Handling request %d\n", request)
}
}
func (h *HardHandler) SetSuccessor(successor Handler) {
// 最后一個(gè)處理者,不設(shè)置后繼者
}
func main() {
// 創(chuàng)建處理者鏈
hardHandler := &HardHandler{}
mediumHandler := &MediumHandler{}
easyHandler := &EasyHandler{}
// 設(shè)置處理者的后繼者
easyHandler.SetSuccessor(mediumHandler)
mediumHandler.SetSuccessor(hardHandler)
// 發(fā)送不同難度級(jí)別的請(qǐng)求
requests := []int{5, 15, 60}
for _, request := range requests {
easyHandler.HandleRequest(request)
}
}
在這個(gè) Go 示例中,我們定義了一個(gè) Handler 接口和三個(gè)具體的處理者類(lèi)型。然后,我們創(chuàng)建了處理者鏈,并設(shè)置了處理者的后繼者。不同難度級(jí)別的請(qǐng)求將由不同的處理者處理,或者傳遞給下一個(gè)處理者。
5.3 Javascript實(shí)現(xiàn)
上述例子用javascript實(shí)現(xiàn)示例如下:
// 抽象處理者類(lèi)
class Handler {
constructor() {
this.successor = null;
}
setSuccessor(successor) {
this.successor = successor;
}
handleRequest(request) {
if (this.successor) {
this.successor.handleRequest(request);
}
}
}
// 具體處理者類(lèi)
class EasyHandler extends Handler {
handleRequest(request) {
if (request <= 10) {
console.log(`EasyHandler: Handling request ${request}`);
} else {
super.handleRequest(request);
}
}
}
class MediumHandler extends Handler {
handleRequest(request) {
if (request > 10 && request <= 50) {
console.log(`MediumHandler: Handling request ${request}`);
} else {
super.handleRequest(request);
}
}
}
class HardHandler extends Handler {
handleRequest(request) {
if (request > 50) {
console.log(`HardHandler: Handling request ${request}`);
}
}
}
// 客戶(hù)端代碼
const hardHandler = new HardHandler();
const mediumHandler = new MediumHandler();
const easyHandler = new EasyHandler();
easyHandler.setSuccessor(mediumHandler);
mediumHandler.setSuccessor(hardHandler);
const requests = [5, 15, 60];
for (const request of requests) {
easyHandler.handleRequest(request);
}
在這個(gè) JavaScript 示例中,我們定義了一個(gè) Handler 類(lèi)作為抽象處理者,并創(chuàng)建了三個(gè)具體處理者類(lèi) EasyHandler、MediumHandler 和 HardHandler。然后,我們?cè)O(shè)置了處理者的后繼者,并發(fā)送不同難度級(jí)別的請(qǐng)求。根據(jù)請(qǐng)求的難度級(jí)別,不同的處理者將負(fù)責(zé)處理請(qǐng)求或?qū)⑵鋫鬟f給下一個(gè)處理者。
5.4 C++實(shí)現(xiàn)
上述例子用C++實(shí)現(xiàn)如下:
#include <iostream>
// 抽象處理者類(lèi)
class Handler {
public:
virtual void handleRequest(int request) {
if (successor) {
successor->handleRequest(request);
}
}
void setSuccessor(Handler* successor) {
this->successor = successor;
}
private:
Handler* successor = nullptr;
};
// 具體處理者類(lèi)
class EasyHandler : public Handler {
public:
void handleRequest(int request) override {
if (request <= 10) {
std::cout << "EasyHandler: Handling request " << request << std::endl;
} else {
Handler::handleRequest(request);
}
}
};
class MediumHandler : public Handler {
public:
void handleRequest(int request) override {
if (request > 10 && request <= 50) {
std::cout << "MediumHandler: Handling request " << request << std::endl;
} else {
Handler::handleRequest(request);
}
}
};
class HardHandler : public Handler {
public:
void handleRequest(int request) override {
if (request > 50) {
std::cout << "HardHandler: Handling request " << request << std::endl;
}
}
};
int main() {
// 創(chuàng)建處理者鏈
HardHandler hardHandler;
MediumHandler mediumHandler;
EasyHandler easyHandler;
// 設(shè)置處理者的后繼者
easyHandler.setSuccessor(&mediumHandler);
mediumHandler.setSuccessor(&hardHandler);
// 發(fā)送不同難度級(jí)別的請(qǐng)求
int requests[] = {5, 15, 60};
for (int request : requests) {
easyHandler.handleRequest(request);
}
return 0;
}
在這個(gè) C++ 示例中,我們定義了一個(gè) Handler 類(lèi)作為抽象處理者,并創(chuàng)建了三個(gè)具體處理者類(lèi) EasyHandler、MediumHandler 和 HardHandler。然后,我們?cè)O(shè)置了處理者的后繼者,并發(fā)送不同難度級(jí)別的請(qǐng)求。根據(jù)請(qǐng)求的難度級(jí)別,不同的處理者將負(fù)責(zé)處理請(qǐng)求或?qū)⑵鋫鬟f給下一個(gè)處理者。
6. 練習(xí)題
當(dāng)用戶(hù)注冊(cè)一個(gè)賬戶(hù)時(shí),通常需要進(jìn)行一系列驗(yàn)證,如用戶(hù)名是否重復(fù)、密碼是否符合規(guī)范、郵箱是否有效等。使用責(zé)任鏈模式來(lái)處理這些驗(yàn)證可以讓代碼更靈活和可擴(kuò)展。
要求:
使用責(zé)任鏈模式實(shí)現(xiàn)以下驗(yàn)證步驟:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-725195.html
- 用戶(hù)名是否重復(fù)驗(yàn)證:檢查用戶(hù)名是否已經(jīng)存在于數(shù)據(jù)庫(kù)中,如果存在則驗(yàn)證失敗,否則繼續(xù)下一步。
- 密碼復(fù)雜度驗(yàn)證:檢查密碼是否符合一定的復(fù)雜度規(guī)范,如包含至少一個(gè)大寫(xiě)字母、一個(gè)小寫(xiě)字母和一個(gè)數(shù)字,否則驗(yàn)證失敗,否則繼續(xù)下一步。
- 郵箱有效性驗(yàn)證:檢查郵箱地址是否有效,如果無(wú)效則驗(yàn)證失敗,否則驗(yàn)證成功。
使用責(zé)任鏈模式創(chuàng)建一個(gè)驗(yàn)證鏈,將驗(yàn)證步驟串聯(lián)起來(lái)。如果某個(gè)驗(yàn)證步驟失敗,驗(yàn)證就會(huì)停止并返回失敗結(jié)果;如果所有驗(yàn)證步驟都通過(guò),驗(yàn)證將返回成功結(jié)果。
你可以使用 C++、Java、Python 或任何其他編程語(yǔ)言來(lái)實(shí)現(xiàn)這個(gè)練習(xí)。
你可以在評(píng)論區(qū)里或者私信我回復(fù)您的答案,這樣我或者大家都能幫你解答,期待著你的回復(fù)~文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-725195.html
到了這里,關(guān)于設(shè)計(jì)模式——22. 責(zé)任鏈模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!