Mình là TUẤN hiện đang là một Full-stack Web Developer tại Tokyo 😊.
Nếu bạn thấy Blog nà y hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé 😉.
Cách sỠdụng Chain of Responsibility bằng TypeScript để giải quyết các vấn đỠthực tế trong các project web.
Chà o mừng bạn đến vá»›i loạt bà i Design Patterns trong TypeScript, loạt bà i nà y mình sẽ giá»›i thiệu má»™t số Design Patterns hữu Ãch trong phát triển web bằng TypeScript.
Các Design Patterns rất quan trá»ng đối vá»›i các web developer và chúng ta có thể code tốt hÆ¡n bằng cách thà nh thạo chúng. Trong bà i viết nà y, mình sẽ sá» dụng TypeScript để giá»›i thiệu Chain of Responsibility.
Các Design Patterns rất quan trá»ng đối vá»›i các Dev web và chúng ta có thể good code hÆ¡n bằng cách thà nh thạo chúng. Trong bà i viết nà y, mình sẽ sá» dụng TypeScript để giá»›i thiệu Chain of Responsibility .
Chain of Responsibility
Chain of Responsibility là một cách để tránh ghép nối giữa sender
và receiver
của các request bằng cách cho nhiá»u đối tượng xá» lý request. Trong Chain of Responsibility, nhiá»u đối tượng được kết nối bằng má»™t tham chiếu từ má»—i đối tượng đến đối tượng tiếp theo của nó để tạo thà nh má»™t chuá»—i (next,next,next…). Các request được truyá»n dá»c theo chuá»—i cho đến khi má»™t trong các đối tượng trong chuá»—i quyết định xá» lý request.
Các vị trà khác nhau trong công ty có trách nhiệm và quyá»n hạn khác nhau. Lấy và dụ vá» quy trình nghỉ của má»™t công ty, khi xin nghỉ chỉ cần được sá»± đồng ý của tổ trưởng, không cần phải chuyển cho cấp trên và giám đốc. Nếu má»™t liên kết trong Chain of Responsibility không thể xá» lý request hiện tại, nếu có liên kết tiếp theo, request sẽ được chuyển tiếp đến liên kết tiếp theo để xá» lý.
Trong quá trình phát triển phần má»m, đối vá»›i Chain of Responsibility, má»™t kịch bản ứng dụng phổ biến là middleware. Chúng ta hãy xem cách sá» dụng Chain of Responsibility để xá» lý các request.
Äể hiểu rõ hÆ¡n vá» Ä‘oạn code sau, trÆ°á»›c tiên chúng ta hãy xem sÆ¡ đồ UML tÆ°Æ¡ng ứng:
Trong hình trên, chúng ta xác định một Interface Handler
. Hai hà m sau đây được định nghĩa trong Interface nà y:
- use(h: Handler): Handler => Dùng để đăng ký handler (middleware)
- get(url: string, callback: (data: any) => void): void => Äăng ký get request handler
Handler interface
interfaceHandler{use(h: Handler): Handler;get(url: string,callback:(data: any)=>void):void;}
Sau đó, chúng ta định nghĩa một abstract Class AbstractHandler
, gói gá»n logic xá» lý của Chain of Responsibility. Tức là kết hợp các trình xá» lý khác nhau để tạo thà nh má»™t chuá»—i tham chiếu.
AbstractHandler abstract class
abstract classAbstractHandlerimplementsHandler{
next!: Handler;use(h: Handler){this.next = h;returnthis.next;}get(url: string,callback:(data: any)=>void){if(this.next){returnthis.next.get(url, callback);}}}
Dựa trên abstract Class AbstractHandler
, chúng ta định nghĩa AuthMiddleware
và LoggerMidddleware
tương ứng. AuthMiddleware
middleware được sỠdụng để xỠlý authentication user và LoggerMidddleware
middleware được sỠdụng để ghi log cho từng request.
AuthMiddleware class
classAuthMiddlewareextendsAbstractHandler{
isAuthenticated: boolean;constructor(username: string, password: string){super();this.isAuthenticated =false;if(username ==="bytefer"&& password ==="666"){this.isAuthenticated =true;}}get(url: string,callback:(data: any)=>void){if(this.isAuthenticated){returnsuper.get(url, callback);}else{thrownewError("Not Authorized");}}}
LoggerMiddleware class
classLoggerMiddlewareextendsAbstractHandler{get(url: string,callback:(data: any)=>void){
console.log(`Request url is: ${url}`);returnsuper.get(url, callback);}}
Vá»›i middleware AuthMiddleware
và LoggerMidddleware
, hãy định nghĩa một Route class
để đăng ký các middleware nà y.
Route class
classRouteextendsAbstractHandler{
urlDataMap:{[key: string]: any };constructor(){super();this.urlDataMap ={"/api/todos":[{ title:"Learn Design Pattern"},],"/api/random":()=> Math.random(),};}get(url: string,callback:(data: any)=>void){super.get(url, callback);if(this.urlDataMap.hasOwnProperty(url)){const value =this.urlDataMap[url];const result =typeof value ==="function"?value(): value;callback(result);}}}
Sau khi định nghĩa Route
Route class, chúng ta có thể sỠdụng nó và đăng ký các middleware theo cách sau:
const route =newRoute();
route.use(newAuthMiddleware("bytefer","666")).use(newLoggerMiddleware());
route.get("/api/todos",(data)=>{
console.log(JSON.stringify({ data },null,2));});
route.get("/api/random",(data)=>{
console.log(data);});
Khi bạn chạy thà nh công đoạn code trên, output tương ứng được hiển thị trong hình sau:
Các tình huống sỠdụng của Chain of Responsibility:
- Muốn gá»i request tá»›i má»™t trong nhiá»u đối tượng mà không chỉ định rõ rà ng đối tượng nháºn request.
- Có nhiá»u đối tượng có thể xá» lý má»™t request và đối tượng nà o xá» lý request được xác định tá»± Ä‘á»™ng trong thá»i gian chạy và Client chỉ cần gá»i request đến Chain mà thôi.
Roundup
NhÆ° má»i khi, mình hy vá»ng bạn thÃch bà i viết nà y và há»c thêm được Ä‘iá»u gì đó má»›i.
Cảm Æ¡n và hẹn gặp lại các bạn trong những bà i viết tiếp theo! ðŸ˜
Nếu bạn thấy Blog nà y hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé. Thank you.😉
Ref
*https://tuan200tokyo.blogspot.com/2022/11/blog54-design-patterns-chain-of.html
Nguồn: viblo.asia