Design Patterns: Command Pattern trong TypeScript

Tram Ho

Chào mừng bạn đến với loạt bài Design Patterns trong TypeScript, tại đây mình 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 Command Pattern.

Command Pattern tách rời Caller và Receiver. Cho phép bạn dễ dàng thêm các lệnh khác nhau để thêm các chức năng khác nhau.

Kịch bản sử dụng Pattern

Trên iOS và macOS, đã có chức năng Shortcuts được tích hợp sẵn. Với chức năng này, các bạn có thể thực hiện nhanh chóng thực hiện 1 hoặc nhiều tác vụ. Ví dụ: các tác vụ như gửi tin nhắn nhanh, dịch văn bản, rút ​​ngắn URL và Download tệp.

image.png

Tiếp theo, hãy thực hiện một chức năng tương tự. Trong đoạn code sau, chúng ta định nghĩa một lớp Shortcuts, trong đó chúng ta tạo 5 hàm thành viên như openUrl, shortenUrl, sendMessage, v.v.

Sau đó chúng ta định nghĩa một class UIEventHandler chứa hàm handleAction để xử lý các sự kiện của user.

Phương thức handleAction nhận 2 tham số là actionarg. Type của tham số actionShortcuts, được tạo thông qua utility type Methods. Nếu bạn muốn tìm hiểu thêm về các Mapped types, mình khuyên bạn nên tìm đọc một bài viết của mình về chủ đề này.

Với class UIEventHandler, chúng ta có thể sử dụng nó theo cách sau:

Đối với code trước đó, có vẻ như không có vấn đề gì. Nhưng sau khi phân tích cẩn thận, bạn sẽ thấy các vấn đề sau:

  • Khi gọi hàm handleAction, chúng ta cần đảm bảo rằng tên action đó phải phù hợp với tên của hàm trong lớp Shortcuts.
  • Với sự gia tăng liên tục của các chức năng, sẽ có ngày càng nhiều hàm tương ứng trong lớp Shortcuts. Kết quả là, chúng ta cần liên tục sửa đổi lớp Shortcuts.

Vậy chúng ta nên giải quyết vấn đề trên như thế nào? Đối với vấn đề này, chúng ta có thể sử dụng Command Pattern.

Command Pattern

Trước tiên chúng ta hãy xem sơ đồ UML tương ứng:

image.png

Trên thực tế, chúng ta có thể gói các tác vụ như gửi tin nhắn, dịch văn bản và rút ngắn URL thành các lệnh riêng lẻ.

Trong đoạn code trên, chúng ta sử dụng các keyword interface để xác định type Command. Trong kiểu Command, một hàm execute được định nghĩa để đóng gói logic mà mỗi lệnh cần thực hiện. Với Interface Command, hãy xác định các lệnh cụ thể.

Trong đoạn code trên, chúng ta đã tạo các lớp OpenUrlCommandSendMessageCommand. Trong tương lai, các lệnh của chúng ta sẽ tiếp tục tăng lên. Để thuận tiện cho việc quản lý các lớp lệnh khác nhau, chúng ta cần định nghĩa một lớp để quản lý các lệnh:

Trong lớp CommandManager, hàm registerCommand được sử dụng để đăng ký lệnh. Và hàm executeCommand được sử dụng để thực thi một lệnh. Với lớp CommandManager, hãy cập nhật lớp UIEventHandler đã tạo trước đó.

Sau khi cập nhật lớp UIEventHandler, hãy khai báo chức năng tương ứng của nó.

Trong đoạn code trên, trước tiên chúng ta tạo đối tượng CommandManager và đăng ký 2 lệnh. Sau đó, chúng ta tạo một đối tượng UIEventHandler và sử dụng hàm handleAction trên đối tượng để thực thi lệnh đã đăng ký. Sau khi đoạn code trên được thực thi thành công, Interface điều khiển sẽ xuất thông tin sau:

Trong contexts của text editor và chức năng command-line, Command Pattern cũng thường được sử dụng. Ví dụ: CAC, thư viện của bên thứ ba để tạo chức năng dòng lệnh, cũng sử dụng Command Pattern. Nếu bạn quan tâm, bạn có thể đọc source code tương ứng.

Các kịch bản sử dụng của Command Pattern:

  • Khi cần trừu tượng hóa các hành động thực thi khác nhau, các tham số khác nhau được sử dụng để xác định hành động nào sẽ thực hiện.
  • Hệ thống cần tách rời Caller request và Receiver request để Caller và Receiver không tương tác trực tiếp. Caller request không cần biết sự tồn tại của Receiver, cũng không cần biết Receiver là ai và Receiver không cần quan tâm khi nào nó được gọ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

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo