Design patterns - Chain of Responsibility Pattern

1. Intent

Chain of Responsibility kết nối người gửi một yêu cầu đến nơi nhận yêu cầu của nó bằng cách cho nhiều hơn một đối tượng một cơ hội để xử lý các yêu cầu. Chuỗi các đối tượng tiếp nhận và truyền các yêu cầu theo chuỗi cho đến khi một đối tượng tiếp nhận xử lý nó. Khởi tạo và chạy lại yêu cầu với một đường ống xử lý duy nhất có chứa nhiều xử lý khả thi. Trong mô hình này, thông thường mỗi đối tượng tiếp nhận yêu cầu có chứa tham chiếu đến đối tượng tiếp nhận yêu cầu khác.Nếu một đối tượng không thể xử lý các yêu cầu, nó sẽ gửi yêu cầu đó thông qua message đến đối tượng tiếp theo.

2. Example

Trong phần này, mình xin lấy ra một ví dụ thực tế để các bạn hiểu hơn về ứng dụng của Chain of Responsibility Pattern (Chain). Các ATM sử dụng Chain of Responsibility để xử lý cho cơ chế rút tiền. Ví dụ: bạn rút 2 triệu : máy nhả ra 3 đồng 500k, 4 đồng 100k, 2 đồng 50k. Tại sao lại trả về kết quả như vậy (mà không nhả ra luôn 4 đồng 500k trong khi trong ATM vẫn có thể còn đồng 500k). Hãy thử tưởng tượng, tất cả những người rút tiền đầu tiên (với số tiền > 500k) máy đều nhả về 500k. Điều gì sẽ xảy ra khi ATM hết tiền 500k. Rút 5 triệu mà nhả ra toàn tiền 10k thì rất khó cho công việc kiểm tra lại tiền của người rút.

3. Structure

Handler (bộ xử lý)

Nó xác định các interface để xử lý yêu cầu. Có nghĩa là phân công nhiệm vụ xử lý cụ thể cho từng đối tượng tiếp nhận yêu cầu.

ConcreteHandlerA · B (bộ xử lý cụ thể)

Thực hiện giao diện của "Handler". Xử lý yêu cầu hoặc nếu nó không xử lý được yêu cầu thì gửi yêu cầu đến đối tượng xử lý tiếp theo .

Client (người sử dụng)

Áp dụng "Chain Of Responsibility", tạo ra các yêu cầu và yêu cầu đó sẽ được gửi đến các đối tượng tiếp nhận.

4. Problem

Cần xử lý có hiệu quả các yêu cầu mà có mối quan hệ khó xử lý và phân quyền ưu tiên cho các bộ xử lý nằm trong cùng một đường ống (pipeline). Quan hệ khó xử lý ở đây có thể xảy ra khi 1 chuỗi yêu cầu gửi đến, yêu cầu sau có thể được tiếp nhận xử lý trước nhưng lại cần kết quả trả về từ yêu cầu trước đó (trong 1 đường ống). Ví dụ : có 2 request : request 1 và request 2 được gửi đến. Request1 đến trước gặp processor 1, tuy nhiên processor 1 không thể xử lý request 1 và lại đẩy cho các processor sau nó. Khi đó request 2 được processor 1 chấp nhận xử lý nhưng lại phải chờ kết quả từ request 1 trả về.

5. Discussion

Chain of Responsibility tiếp nhận các yêu cầu khác nhau, và sau đó truyền yêu cầu từ đối tượng này qua đối tượng khác cho đến khi nó tìm đến được một đối tượng có khả năng xử lý các yêu cầu. Số lượng và loại đối tượng xử lý là không quan tâm độ ưu tiên, họ có thể được cấu hình tự động. Cơ chế chain sử dụng thành phần đệ quy để cho phép một số lượng không giới hạn của bộ xử lý cần được liên kết. Hãy chắc chắn rằng có tồn tại một "lưới an toàn" để "bắt" các yêu cầu mà đi không được quản lý. Không sử dụng Chain of Responsibility khi mỗi yêu cầu chỉ được xử lý bởi một bộ xử lý, hoặc khi đối tượng client biết đến dịch vụ mà đối tượng cần xử lý các yêu cầu.

6. Implementation

Chúng tôi đã tạo ra một abstract class AbstractLogger với các level khác nhau của logger.Sau đó, chúng tôi đã tạo ra ba loại logger kế thừa AbstractLogger. Mỗi logger kiểm tra mức độ thông tin với trình độ và in ấn phù hợp với nó. Nếu không, in ra thông tin và truyền thông điệp đến logger tiếp theo của nó.

Source code tham khảo tại : https://www.tutorialspoint.com/design_pattern/chain_of_responsibility_pattern.htm

7.Referenced documents

https://www.tutorialspoint.com/design_pattern/chain_of_responsibility_pattern.htm https://sourcemaking.com/design_patterns/chain_of_responsibility https://github.com/iluwatar/java-design-patterns/tree/master/chain


All Rights Reserved