將請求的處理程序分成多個處理器,並讓每個處理器決定如何處理請求。
想像蘋果工廠的流水線上有一系列工作站,分別負責清洗、選別和包裝。每個工作站會依序處理蘋果,並將其傳送至下一個站。如果在選別站發現蘋果有嚴重破損或蟲害,蘋果會被挑出並提前終止處理程序。這些工作站就像責任鏈模式中的處理器,每個站都有特定的職責,可以選擇處理或將蘋果傳遞至下一個站,也可以提前終止流程。
大家對於前後端應用程式中的路由應該不陌生。路由器會依照順序比對每個路徑,將請求交給對應的處理器,這與責任鏈模式的設計概念非常相似。我們來實作一個簡易版的音樂伺服器路由,看看如何運用責任鏈模式來開發程式。
首先,定義一個抽象的路由處理器。每個路由器具體的處理器都要實現自己的處理邏輯。我們利用 setSuccessor
方法可以設定下個處理器,並透過 next
方法將請求傳遞至下個處理器。
abstract class RequestHandler {
private successor?: RequestHandler;
abstract handle(request: Request): void;
setSuccessor(successor: RequestHandler) {
this.successor = successor;
}
protected next(request: Request) {
this.successor?.handle(request);
}
}
實作具體處理器。日誌程式用來紀錄每個請求路徑,專輯程式則會回應一個專輯列表給使用者。
class Logger extends RequestHandler {
handle(request: Request) {
console.log(`Logger: Received request for ${request.pathname}`);
this.next(request);
}
}
class AlbumsHandler extends RequestHandler {
handle(request: Request) {
if (request.pathname !== "/albums") {
return this.next(request);
}
console.log("AlbumsHandler: Sending several albums to user");
}
}
設計伺服器程式。每當伺服器收到一個新的請求時,會將請求交給第一個處理器,並讓處理器決定要處理請求,或將請求傳遞至下一個處理器。
class Server {
private handlers: RequestHandler[];
constructor() {
this.handlers = [];
}
use(handler: RequestHandler) {
const previousHandler = this.handlers[this.handlers.length - 1];
previousHandler?.setSuccessor(handler);
this.handlers.push(handler);
}
process(request: Request) {
if (this.handlers.length > 0) {
this.handlers[0].handle(request);
}
}
listen() {
console.log("Listening for incoming requests...");
}
}
測試伺服器。
class ServerTestDrive {
static main() {
const server = new Server();
const logger = new Logger();
const albumsHandler = new AlbumsHandler();
const artistsHandler = new ArtistsHandler();
server.use(logger);
server.use(albumsHandler);
server.use(artistsHandler);
server.listen();
server.process(new Request("/albums"));
server.process(new Request("/artists"));
server.process(new Request("/unknown"));
}
}
ServerTestDrive.main();
輸出結果。
Listening for incoming requests...
Logger: Received request for /albums
AlbumsHandler: Sending several albums to user
Logger: Received request for /artists
ArtistsHandler: Sending several artists to user
Logger: Received request for /unknown
責任鏈模式包含兩個角色:
責任鏈模式將請求的處理程序分成多個處理器,讓每個處理器專注於特定的任務,藉此分散職責。這樣的設計可以降低程式間的依賴性,讓系統更容易維護與擴充。責任鏈會將請求依序傳遞至各個處理器,直到請求被處理,或是所有處理器都執行完畢。每個處理器可以自行選擇要處理或忽略請求,也能視情況提前終止責任鏈。