Những lợi thế của mẫu đại biểu so với mẫu quan sát viên là gì?


9

Trong mẫu đại biểu , chỉ một đối tượng có thể nghe trực tiếp các sự kiện của đối tượng khác. Trong mẫu quan sát viên , bất kỳ số lượng đối tượng nào cũng có thể lắng nghe các sự kiện của một đối tượng cụ thể. Khi thiết kế một lớp cần thông báo cho (các) đối tượng khác về các sự kiện, tại sao bạn lại sử dụng mẫu đại biểu trên mẫu quan sát viên? Tôi thấy mô hình quan sát là linh hoạt hơn. Bạn có thể chỉ có một người quan sát bây giờ, nhưng một thiết kế trong tương lai có thể yêu cầu nhiều người quan sát.


4
Bạn có ý nghĩa gì bởi "mẫu đại biểu"? Nếu bạn đang nói về một cái gì đó như đại biểu của .net, bạn có thể có nhiều người đăng ký như bạn muốn.
CodeInChaos

Liên quan, mặc dù tập trung nhiều hơn vào Ca cao: NSNotificationCenter so với ủy quyền (sử dụng giao thức)?
mouviciel

Câu trả lời:


7

Không có mẫu đại biểu cho mỗi se. Tôi sẽ giả sử bạn có nghĩa là Mô hình Đoàn .

Theo tôi hiểu, chúng hoàn toàn ngược lại với nhau và được sử dụng cho các mục đích khác nhau.

Nói chung, với Mẫu Người quan sát , bất kỳ số lượng đối tượng quan sát viên nào cũng sẽ lắng nghe một sự kiện trên đối tượng thứ hai và hành động theo sự kiện đó. Đối tượng thứ hai không có kiến ​​thức về người nghe của nó. Nó chỉ gọi họ.

Một đối tượng ủy nhiệm được truyền cho đối tượng thứ hai gọi các phương thức trực tiếp trên đại biểu. Và đó là lợi thế bạn đang tìm kiếm. Thay vì gửi một tin nhắn đến nhiều người nghe, nó có toàn quyền kiểm soát một đối tượng (tại một thời điểm nhất định). Xem thêm Đảo ngược điều khiển .


6

Bạn đang nhìn mọi thứ không chính xác. Một người quan sát thấy rằng một sự kiện cụ thể xảy ra. Nó không ảnh hưởng đến nó, hoặc sở hữu nó. Một đại biểu xử lý một sự kiện cụ thể và có quyền sở hữu của người xử lý, ngay cả khi đại biểu sở hữu giao diện cho sự kiện đó.


1
Một đại biểu thực sự không gì khác hơn là một người quan sát sự kiện. Một đại biểu không cần phải "xử lý" bất cứ điều gì. Nó hoàn toàn không thể làm gì và sẽ không (hoặc ít nhất là không) ảnh hưởng đến trường hợp đã kích hoạt sự kiện.
Marjan Venema

5
@MarjanVenema - nếu đối tượng A không ủy thác trách nhiệm cho sự kiện cho đối tượng B, thì bạn không sử dụng mẫu ủy nhiệm: bạn đang sử dụng mẫu quan sát viên chỉ có một người quan sát.
Telastyn

Vâng, đó là những gì tôi đã nghĩ đến. Tôi hiểu rằng ủy thác là loại chữ ký sự kiện sẽ được sử dụng bởi người đăng ký của một sự kiện "OnWhthing". Rõ ràng các đại biểu trong C # không phải là người đăng ký đơn lẻ như họ là ví dụ Delphi.
Marjan Venema

@Marjan Venema "Một đại biểu thực sự không gì khác hơn là một người quan sát sự kiện." - nó phụ thuộc vào ngôn ngữ bạn đang nói về. Trong Mục tiêu C, một số đại biểu chịu trách nhiệm cung cấp dữ liệu - ví dụ: đại biểu dữ liệu - và một đối tượng thiếu một đại biểu dữ liệu không có dữ liệu để trình bày. Trong những trường hợp đó, có sự ủy thác xảy ra, khác với hành động chỉ quan sát một cái gì đó.
thỉnh thoảng

1
@occulus: cảm ơn đã làm rõ. Đáng tiếc là các ngôn ngữ không thể đồng ý về thuật ngữ ... Nói về lập trình theo cách bất khả tri ngôn ngữ trở nên hơi khó khăn khi mọi người hiểu những điều khác nhau cho cùng một từ.
Marjan Venema

4

Đó là một câu hỏi của một số sự đánh đổi.

Đánh đổi:

  • tính linh hoạt (về việc có n> 1 đại biểu / quan sát viên)
  • chi phí gửi tin nhắn
  • khả năng phục hồi (khả năng duy trì sự không có sẵn của đại biểu / quan sát viên)
  • dễ sử dụng

Mẫu đại biểu:

  • không linh hoạt - không thể thêm nhiều hơn 1 đại biểu (ngụ ý một số dạng "đa đại biểu" tức là mẫu quan sát viên)
  • gửi tin nhắn rẻ, O (1) - chi phí tương tự như gọi bất kỳ chức năng hoặc phương thức nào khác (không cần tra cứu, xếp hàng tin nhắn hoặc cơ sở hạ tầng khác)
  • thường không kiên cường - các đại biểu dự kiến ​​sẽ có mặt và thực hiện phần công việc của họ, tức là người gửi có xu hướng thất bại nếu không biết đại biểu
  • dễ nắm bắt, dễ thực hiện

Mẫu quan sát viên:

  • rất linh hoạt - thiết kế thêm n> 1 người quan sát
  • gửi tin nhắn có chi phí ngụ ý theo số lượng người quan sát, O (n), tức là n người quan sát mất n thời gian và tin nhắn (ít nhất là trong một triển khai ngây thơ)
  • thường có khả năng phục hồi - các nhà quan sát thường không mong muốn thực hiện bất kỳ công việc nào trên một phần của người gửi. Đó là ngay cả khi không có người quan sát, người gửi không bị ảnh hưởng
  • có thể trở nên khá phức tạp để nắm bắt, đặc biệt là các nhà quan sát dự kiến ​​sẽ phản ứng với các thông điệp (thứ tự có quan trọng không?, người quan sát nào phản ứng theo cách nào?)

1

Mẫu đại biểu, như tôi hiểu bạn, được biết đến như là cơ chế xử lý sự kiện trong các ngôn ngữ khác, ví dụ Delphi. Như vậy, nó chỉ đơn giản là một triển khai của mẫu quan sát viên với một hạn chế lớn: chỉ có một người nghe tại một thời điểm.

Nhược điểm của người xử lý sự kiện hoặc đại biểu là rõ ràng: chỉ có một người quan sát.

Ưu điểm không quá rõ ràng: hiệu suất. Với một mẫu quan sát, bạn có thể thêm nhiều người quan sát. Khi một sự kiện xảy ra mà người quan sát cần được thông báo, bạn sẽ cần liệt kê những người quan sát và gửi thông báo cho mỗi người quan sát. Điều này có thể nhanh chóng làm hỏng bất kỳ trường hợp quan sát nào, đặc biệt là khi số lượng sự kiện yêu cầu thông báo cũng rất quan trọng.


Huh? Đại biểu C # chỉ là chữ ký của một phương thức dưới dạng một biến (ví dụ, tương đương với, int (*my_int_f)(int)trong C). Tôi đã luôn nghĩ rằng họ đã làm cho điều đó trở nên dễ hiểu hơn bằng cách làm cho nó hoạt động giống như struct / enum hơn. Một sự kiện là một cái móc cho một mảng người nghe linh hoạt, sử dụng một chữ ký đại biểu duy nhất. Bạn có thể làm điều đó mà không cần sự kiện (đó là lý do tại sao tôi cho rằng OP có nghĩa là Mẫu ủy nhiệm, rất khác biệt), nhưng ngôn ngữ sẽ giúp bạn dễ dàng hơn.
pdr

hmm Chưa thành thạo về C #. Tôi hiểu rằng các đại biểu tương đương với các loại chữ ký sự kiện như được sử dụng bởi các sự kiện "OnWhthing" trong ví dụ Delphi. Vì vậy, các sự kiện C # có thể được đăng ký bởi nhiều người nghe?
Marjan Venema

Hành động chung <T> là một đại biểu. Nó không liên quan gì đến các sự kiện, đó là một biến được truyền qua. Và vâng, nhiều người nghe có thể nghe một sự kiện.
pdr

ok cảm ơn, hy vọng tôi có thể giữ thẳng ... :-) Lấy ra tham chiếu C # và tập trung hơn vào cơ chế sự kiện.
Marjan Venema

1

Đây là một bài viết cũ nhưng dù sao tôi cũng sẽ đồng ý vì các câu trả lời khác không giải quyết được những gì đang xảy ra khi sử dụng một trong hai mẫu, chúng dường như thiên về lý thuyết hơn là thực hành.

Cách thức hoạt động của Đoàn và Quan sát viên

Với Phái đoàn, đại biểu chọn chính xác người sẽ phản ứng với một sự kiện cụ thể vào thời điểm nguồn gốc của sự kiện tiềm năng được tạo ra. Bạn có thể nghĩ về người nghe này như một người quan sát duy nhất . Trong trường hợp mẫu Người quan sát, người quan sát chọn người mà họ đang quan sát bất cứ khi nào cảm thấy như vậy; vì vậy các phụ thuộc được đảo ngược khi nói đến người quan sát so với phái đoàn. Với mô hình quan sát, hãy nghĩ về một tờ báo và người đăng ký như những người quan sát. Các nhà quan sát kiểm soát thời điểm mối quan hệ được tạo ra. Với phái đoàn nghĩ về một nhân viên và một chủ nhân. Nhà tuyển dụng kiểm soát thời điểm mối quan hệ được tạo ra và chính xác ai là người chịu trách nhiệm cho các sự kiện cụ thể. Nhân viên không thể chọn những nhiệm vụ họ đang làm ... nói chung.

Một số phái đoàn tranh luận có thể có một người quan sát nhưng tôi nghĩ rằng sự khác biệt thực sự giữa hai người là cách xử lý sự kiện được chỉ định. Bạn sẽ không bao giờ thấy một đại biểu đăng ký cho một sự kiện. Nó sẽ không bao giờ biết nó thậm chí xử lý sự kiện cho đến khi nó xảy ra và đại biểu gọi một phương thức công khai trên nó.

Lợi thế của phái đoàn

Mẫu này rất cứng nhắc và với hầu hết các thiết kế regid đơn giản hơn và thường mạnh mẽ hơn. Nó buộc bạn phải khai báo xử lý sự kiện của bạn lên phía trước tại thời điểm khởi tạo nguồn của sự kiện tiềm năng. Nếu bạn cần ai đó điều khiển giao thông, bạn chỉ định một giám đốc giao thông trước khi bạn mở đường. Trong trường hợp của người quan sát, bạn sẽ cho phép cảnh sát giao thông chọn thời điểm điều khiển giao thông bất cứ khi nào họ cảm thấy thích.

Bất lợi cho đoàn

Nhược điểm của thiết kế này là nó không linh hoạt. Nếu bạn đang thực hiện một số mã để đăng ký một tờ báo, tờ báo / đại biểu sẽ phải xác định chính xác ai có thể đọc những câu chuyện tin tức thứ hai mà họ được tạo. Với mẫu người quan sát họ có thể đăng ký sau bất cứ lúc nào và tờ báo sẽ chỉ phải biết rằng một người mới đã đăng ký.

Khi nào nên chọn Đoàn?

Khi bạn cần một người quan sát cụ thể chắc chắn và không có lý do gì để bạn thay đổi người đang quan sát thì thiết kế cứng nhắc của mẫu ủy nhiệm sẽ có lợi.

Ví dụ: bạn cần một lớp / đối tượng để xử lý việc tạo một cửa sổ bật lên cho một lỗi cụ thể. Không có nhiều lý do tại sao vào thời gian chạy, bạn sẽ cần phải chuyển người đang xử lý một lỗi cụ thể để ủy thác lỗi "Hết bộ nhớ" cho một thực thể duy nhất sẽ có ý nghĩa. Tạo một mảng các trình xử lý tiềm năng và sau đó các trình xử lý đó đăng ký cho lỗi "Hết bộ nhớ" sẽ không có ý nghĩa gì nhiều; đó sẽ là một ví dụ về việc sử dụng mẫu quan sát viên trong tình huống này. Vào thời gian chạy, bạn có thể muốn thay đổi phương thức nào được gọi hoặc "đại biểu" nào được gọi cho các sự kiện thay đổi nhưng việc trao đổi một trình xử lý sự kiện cho một sự kiện cụ thể vào thời gian chạy là không bình thường.

Không thể trao đổi các đại biểu như bạn sẽ làm trong mô hình quan sát viên, nó chỉ phức tạp. Trong thế giới thực, có lẽ bạn muốn trao đổi cảnh sát giao thông để một đại biểu mới đang xử lý lưu lượng. Người ta có thể lập luận rằng một thiết kế tốt hơn sẽ biến đại biểu ban đầu thành một đồn cảnh sát và không phải là một sĩ quan cảnh sát duy nhất mà tôi ...

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.