0

Design Pattern - Command

Command có thể gọi là một pattern đa năng

Vì sao ư, hãy cũng tìm xem vì sao nhé.

Tưởng tượng bạn đang xây dựng SlickUI(là một framework GUI). Bạn đang bận rộn tạo ra những button đẹp, những dialogs tuyệt vời và những icon bắt mắt. Nhưng mỗi lần bạn kết thúc công việc tạo ra framework giao diện bắt mắt, bạn lại phải đối mặt với một vấn đề : “Làm thế nào bạn dùng giao diện đó để làm vài thứ có ích khác.”

Cụ thể hơn, bạn có thể tưởng tượng mình m xây dựng class button với method on_button_push có thể được gọi bất cứ khi nào người dùng click trên màn hình:

class SlickButton
  #
  # Lots of button drawing and management
  # code omitted...
  #
   def on_button_push
     #
     # Do something when the button is pushed
     #
   end
end

Nhưng bạn nên làm gì trong method on_button_push? Bạn hy vọng SlickUI sẽ phổ biến và được sử dụng bởi hàng nghìn lập trình viên trên thế giới, những người sẽ tạo ra hàng triệu instances của SlickButton.

Có lẽ một team lập trình sẽ xây dựng một bộ xử lý văn bản và sẽ cần tới button để tạo hoặc lưu tài liệu chẳng hạn. Team khác phải làm việc trên network utility và hộ phải cần một button để khởi tạo kết nối mạng. Vấn đề là trong khi khi bạn đang xây dựng class SlickButton, bạn không có ý tưởng gì về bất cứ button nào phải làm.

Một giải pháp cho vấn đề này rất phổ biến đó là inheritance. Bạn có thể yêu cầu người phát triển tạo một subclass cho mỗi loại button khác nhau.

class SaveButton < SlickButton
  def on_button_push
    #
    # Save the current document...
    #
  end
end

Nhưng thật không may, vì một ứng dụng GUI phức tạp sẽ có khoảng 10 với hàng trăm buttons, và như thế chúng ta phải có 10 tới hàng trăm subclass của SlickButton ư ? Hơn nữa, còn có những loại element GUI khác, như menu items, radio button. Bạn có thể hoặc muốn các nhà phát triển mã nguồn của mình phải làm những việc như thế không? Nếu không thì phải làm thế nào mới tốt nhất?

Liệu có một cách giải quyết đơn giản hơn?

Phương án cho vấn đề này là đóng gói ý tượng, những action cần làm khi button được ấn hoặc menu iteam được chọn. Tức là gom code để xử lý việc ấn button hoặc chọn menu trong object riêng. Những action này chính là những commands của Command pattern.

Để ứng dụng Command pattern vào button của bạn, chúng tôi đơn giản là lưu object command với mỗi button.

class SlickButton
  attr_accessor :command
  def initialize(command)
    @command = command
  end
  #
  # Lots of button drawing and management
  # code omitted...
  #
  def on_button_push
    @command.execute if @command
  end
end

Sau đó chúng ta chỉ việc định nghĩa command cho mọi thứ mà button phải làm:

class SaveCommand
  def execute
    #
    # Save the current document...
    #
  end
end

Ý tưởng của pattern

Xây dựng code action trong chính đối tượng của nó là cốt lõi của Command pattern.

Pattern này phân tách những thứ thay đổi, những thứ mà chúng ta muốn thực hiện khi button được ấn, từ những thứ không đổi.

Tham khảo

Github (updating):https://github.com/ducnhat1989/design-patterns-in-ruby

Sách: “DESIGN PATTERNS IN RUBY” của tác giả Russ Olsen

Bài viết liên quan:


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí