Thứ Hai, 24 tháng 9, 2012

Chain of Responsibility Pattern

dạo này thích viết bằng html hơn là dùng RichText nên mọi người thông cảm >:)

Nếu các bạn đã từng nghe qua về 23 mẫu Design Pattern của nhóm GOF thì thật tốt vì hôm nay chúng ta sẽ nói về mẫu lập trình trong 23 mẫu đó trong 1 bộ môn có tên là "Kiến trúc phần mềm" do Tiến Sỹ Trần Minh Triết đang giảng dạy...

23 mẫu Design Pattern thường dùng được chia thành 3 "phân vùng" gồm
  • Creational Patterns: các mẫu thiết kế thiên về tạo lập và quản lý tạo lập đối tượng
  • Behavioral Patterns: các mẫu thiết kế thiên về phương thức xử lý và quan hệ giữa các class
  • Structural Patterns: các mẫu thiết kế liên quan đến kiến trúc của phần mềm

Ngày hôm nay tạm gác qua các mẫu về Creational Patterns (sẽ được trình bày ở dịp khác) chúng ta đi vào phần Behavioral Patterns.

Như đã trình bày ở trên, các mẫu thiết kế liên quan đến behavioral patterns là những bài giải mẫu liên quan đến việc điều khiển các luồng xử lý và mối liên hệ giữa các class ... Bắt đầu luôn chứ không dài dòng nữa.


Mẫu số 1: Chain of Responsibility Pattern

Chain of Responbility để làm gì???
Giống như tên gọi của nó ... Chain of Responsibility là một mẫu thiết kế giải quyết cho việc thực hiện 1 chuỗi các tác vụ có trình tự mà mỗi 1 tác vụ trong chuỗi đó được đảm nhiệm bởi 1 class.

Ví dụ :
Mua bột --> Nhào bột --> Nướng bánh --> Nhậu

Đó là ví dụ đơn giản về 1 chuỗi các công việc. Mỗi công việc ở trên do một người đảm nhiệm:

phụ việc : đi chợ
phụ bếp : nhào bột
Đầu bếp : Nướng bánh
Thực khách : nhậu

Trong đó Phụ việc, phụ bếp, đầu bếp, thực khách là các class và Đi chợ(), nhào bột(), Nướng bánh(), nhậu() là các phương thức (method).

Hãy tưởng tượng đến 1 sợi dây xích có nhiều mắc xích ...

Trong mẫu Chain of Responsibility chúng ta có một thành phần chính là Handler. Handler là đối tượng đóng gói phương thức xử lý của instances này vào 1 instances khác (xem phần sau sẽ rõ)



Tạm quên UML của nó 1 bên vì nó không cung cấp nhiều thông tin lắm về mẫu này ... ta đến với vấn đề mẫu...

Vấn đề: Một nhóm các class xử lý theo lượt nhưng không có cách nào xác định thứ tự cái nào sẽ được gọi trước.

Ví dụ 1 luồng công việc như sau

 Process firstProcess = new FirstProcess();  
 fistProcess.Run();  
 Process secondProcess = new SecondProcess();  
 secondProcess.Run();  
 Process thirdProcess = new ThirdProcess();  
 thirdProcess.Run();  

Trong đó Process là lớp cha ... các lớp FirstProcess, SecondProcess, ThirdProcess() là các lớp kế thừa.

Giải quyết: Sử dụng một chuỗi class liên hợp để xử lý và định nghĩa bước thực hiện tiếp theo trong hàm xử lý của các class này.

Sơ đồ UML


Chúng ta đặt class thực thi tiếp theo vào class hiện tại, cho phép mỗi class chứa thể hiện (instance) của class tiếp theo trong chuỗi mắc xích.

#RunNext() bao gồm Run() và SetNextProcess()... 2 hàm này sẽ đảm bảo tại mỗi một mắc xích nó sẽ làm đúng nhiệm vụ của mình và ủy thác phần còn lại cho "mắc xích" tiếp theo cho đến khi hết.

Code cài đặt :


 abstract class Process  
 {  
   private Process _nextProcess;  
   protected abstract void RunNext();  
   public void Run()  
   {  
      RunNext();  
      if(_nextProcess != null)  
      {  
        _nextProcess.Run();  
      }  
   }  
   public void SetNextProcess(Process process)  
   {  
      _nextProcess = process;  
   }  
 }  


 class FirstProcess : Process  
 {  
   Protect override void RunNext()  
   {  
     System.Threading.Thread.Sleep(1000);  
   }  
 }  
 class SecondProcess: Process  
 {  
   Protect override void RunNext()  
   {  
     System.Threading.Thread.Sleep(2000);  
   }  
 }  
 class ThirdProcess: Process  
 {  
   Protect override void RunNext()  
   {  
     System.Threading.Thread.Sleep(3000);  
   }  
 }  

Thực thi vấn đề

 Process firstProcess = new FirstProcess();  
 Process secondProcess = new SecondProcess();  
 Process thirdProcess = new ThirdProcess();  
 firstProcess.SetNextProcess(secondProcess);  
 secondProcess.SetNextProcess(thirdProcess);  
 thirdProcess.SetNextProcess(null);  
 firstProcess.Run();  

Kết quả:

 Beginning first process ....  
 Ending first process ....  
 Beginning second process ....  
 Ending second process ....  
 Beginning third process ....  
 Ending third process ....  

Vậy ta đã thực thi được 1 chuỗi các hành động theo mắc xích bằng cách "chỉ ra mắc xích" tiếp theo của mắc xích hiện tại... Đó cũng là tinh thần của Chain of Responbility...

3 nhận xét: