Khi nào móc là sự lựa chọn thiết kế đúng?


10

Tôi đã làm việc trên một ứng dụng Rails lớn, nơi việc sử dụng các cuộc gọi lại ActiveRecord đang lan tràn và bừa bộn. Lưu một bản ghi thường có tác dụng phụ không mong muốn và đó là một thách thức đối với lý do về hệ thống.

Đồng thời, tôi đã thấy các hook được sử dụng để tạo hiệu ứng tốt như là một phần của thừa kế (ví dụ: lớp cha sử dụng phương thức mẫu để cho phép các lớp con thêm hành vi chuyên biệt mà không cần biết về nội bộ của cha mẹ) và trong các trình cắm thêm (ví dụ: chế độ emacs chạy hook khi được kích hoạt, cho phép người dùng thêm hành vi tùy chỉnh xung quanh chế độ đó).

Tôi nhận ra rằng ứng dụng Rails và trình thông dịch Lisp là những hệ thống rất khác nhau, nhưng tôi tò mò liệu có bất kỳ tiêu chí nổi tiếng nào mà mọi người tìm đến khi quyết định xem móc có phải là lựa chọn thiết kế phù hợp cho vấn đề họ gặp phải hay không.

Chủ đề nhảy ra với tôi là dự đoán. Việc lạm dụng móc dường như dẫn đến hành động ma quái ở khoảng cách xa và hành vi đáng ngạc nhiên, trong khi sử dụng tốt có thể dẫn đến một khuôn khổ có thể dự đoán được mà không cần khớp nối chặt chẽ.

Vì tôi vẫn chỉ còn vài năm trong sự nghiệp lập trình của mình, tôi coi mình là một người không chuyên về nhiều khía cạnh và mọi người nghi ngờ đã đặt một số lượng lớn suy nghĩ vào chủ đề này. Một số hướng dẫn có thể chỉ đạo quyết định này là gì?

Câu trả lời:


5

Móc là một lựa chọn thiết kế tốt khi bạn muốn tách rời các chi tiết triển khai của một sự trừu tượng hóa từ người tiêu dùng bằng cách chuyển quyền kiểm soát sang các máy thu của móc.

Bạn có thể thực hiện điều đó bằng một chương trình phát sóng ẩn danh (như các sự kiện hoặc cuộc gọi lại ẩn danh) hoặc bằng cách sử dụng các tóm tắt được gõ (như Giao diện hoặc các lớp cha).

Bạn nên sử dụng phát sóng ẩn danh khi:

  • Cuộc gọi của hook là tùy chọn
  • Người gọi không quan tâm ai sắp xếp lại cái móc.
  • Trình tự thực hiện của người nhận là không liên quan.
  • Bạn muốn phát trạng thái đối tượng cho tất cả những người đăng ký vào hook.

Bạn nên sử dụng một bản tóm tắt được gõ khi:

  • Gọi móc là bắt buộc.
  • Đối tượng gọi cần xác định người nhận của hook.
  • Thứ tự thực hiện của các máy thu có liên quan đến đối tượng của bạn.

Một ví dụ về hook hook phát sóng là KeyPressionEvent. Lớp phát sinh sự kiện không quan tâm ai nhận nó và đang phát trạng thái bàn phím cho bất kỳ ai đăng ký sự kiện. Thứ tự thực hiện của các máy thu không ảnh hưởng đến trạng thái đối tượng của lớp phát sinh sự kiện.

Một ví dụ về móc trừu tượng được gõ là phương thức mẫu mà bạn đã đề cập. Trong trường hợp này, lớp cha yêu cầu triển khai cho các phương thức mẫu của nó, nó biết rằng các bộ thu sẽ là con của nó và nó có một thứ tự thực hiện cụ thể cho các phương thức mẫu, như được định nghĩa bởi lớp cha.


7

Hầu hết các ngôn ngữ và hầu hết các nền tảng đều sử dụng tính năng kết nối, ngay cả khi nó mặc quần áo như một thứ khác. Bất cứ khi nào bạn nghe thấy thuật ngữ "sự kiện", "tin nhắn", "kích hoạt", "tín hiệu" hoặc các thuật ngữ khác có tính chất đó, bạn có thể xử lý việc móc nối, mặc dù có những ngoại lệ đối với quy tắc, có thể không vấn đề cho cuộc thảo luận này.

Bạn sử dụng chúng vì nền tảng cung cấp chúng cho bạn hoặc thậm chí có thể yêu cầu sử dụng chúng vì lý do hiệu suất. Sử dụng hook thường làm giảm độ phức tạp của mã, giúp thực thi các yêu cầu nghiệp vụ và giảm mức sử dụng CPU, kéo dài tuổi thọ pin và phần cứng. Bạn nên sử dụng chúng bất cứ khi nào bạn muốn hiệu suất tốt nhất từ ​​mã của bạn.

Ngay cả kinh nghiệm bừa bộn của bạn với Rails cũng xác định khá nhiều trường hợp sử dụng chung cho hook: quy tắc kinh doanh phải được thi hành và hook được sử dụng phổ biến để thực thi các quy tắc kinh doanh. Thật không may, không phải tất cả các quy tắc đều có ý nghĩa và như bạn có thể nói, nó khiến mọi nhà phát triển khó khăn hơn khi họ độc đoán, nhưng đó là lý do tại sao tài liệu của một hệ thống cũng quan trọng như chính mã.

Theo nguyên tắc chung, hãy sử dụng hook vì chúng là các tính năng hiệu suất và sẽ làm cho mã của bạn chạy hiệu quả hơn so với giải pháp thay thế (được gọi là "bỏ phiếu", trong đó bạn chờ trong một vòng lặp bận rộn để kiểm tra các sự kiện). Tuy nhiên, cũng đảm bảo rằng bạn sử dụng tài liệu phù hợp và cập nhật nó. Móc được sử dụng trong hầu hết mọi ngôn ngữ bạn sẽ gặp và điều quan trọng là phải biết tại sao chúng tồn tại.


1

Trước đây tôi đã từng làm việc trên một chương trình mà theo ý kiến ​​của tôi là sử dụng tốt các móc. Trong cuốn sách của tôi, một cái móc thực sự là một cuộc gọi (xuất bản) đến một danh sách các cuộc gọi lại (người đăng ký). Đó là mạnh mẽ, lạm dụng là dễ dàng. Câu hỏi tốt nhất để hỏi trường hợp sử dụng là: tôi có muốn bật hoặc tắt hành vi khi chạy không? Ví dụ: bạn có thể muốn cho phép người dùng của mình cung cấp các tập lệnh mà bạn sẽ chạy trong một số sự kiện nhất định hoặc tạo một chương trình chung được tạo từ các plugin nhỏ hơn. Sau đó, các cuộc gọi hook là thích hợp. Nói chung, bạn có ít lựa chọn khác.

Nếu không, bạn nên tránh xa với một mô-đun tốt các mô-đun của bạn. Các phương thức mẫu hoạt động tốt với các hàm quá tải, bạn không cần logic thời gian chạy cho việc này. Xem xét nó sẽ thực thi khớp nối lỏng lẻo là một ảo ảnh: có cùng một mức độ phụ thuộc giữa một cái gì đó bạn gọi trực tiếp hoặc bạn móc, callee dù sao cũng phải điền vào hợp đồng của nó.

Lưu ý rằng, có thể một số người gọi phương thức mẫu có chức năng móc nối quá tải, nhưng điều đó khác với ở trên: ở đây bạn có một liên kết tĩnh, với rủi ro thấp hơn để gặp ác mộng bảo trì.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.