Mẫu đăng ký xuất bản khác với gotos như thế nào?


11

Sự hiểu biết của tôi là các tuyên bố Goto thường được tán thành . Nhưng mẫu đăng ký xuất bản dường như giống nhau về mặt khái niệm ở chỗ khi một đoạn mã xuất bản một thông điệp, nó thực hiện chuyển giao quyền kiểm soát một chiều. Lập trình viên có thể không biết những phần nào của chương trình đang đăng ký vào thông báo này.

Tôi đã thấy một cái gì đó tương tự trong rất nhiều chương trình JavaScript trong đó các sự kiện được sử dụng để "nhảy" thuận tiện trên các mô-đun. Tôi có thiếu điều gì về các mẫu đăng ký xuất bản hoặc hướng sự kiện không?


5
return, try/catch, break, continue, switch- đó là những tất cả goto với mức độ khác nhau của việc hạn chế xây dựng trong Chuyển coi là có hại có hại cho suy nghĩ về cách thức hoạt động mã..

@MichaelT: Đối với phần lớn các trường hợp, có những lựa chọn thay thế cho goto giúp dễ dàng lý luận về mã hơn. Không có hại trong việc đánh giá cao thực tế đó. Tác hại chỉ được thực hiện nếu bạn không sử dụng goto khi được bảo hành (thường là không) hoặc nếu bạn sử dụng goto một cách bất cẩn. Tôi tin rằng Apple đã cho chúng ta thấy một ví dụ tốt về sau này.
back2dos

... không có ý tưởng những gì các bộ phận của chương trình đang đăng ký ... : Sự khác biệt lớn đầu tiên với gotosự dối trá trong s vào cuối phần . Sự khác biệt lớn thứ hai nằm ở không có ý tưởng . Sự khác biệt lớn thứ ba là về mặt khái niệm a gosub, không phải a goto.
mouviciel

1
Nó gần hơn với "đến từ" của INTERCAL.
CodeInChaos

@ back2dos đó cũng là một ví dụ tốt về lý do tại sao tôi thích sử dụng dấu ngoặc nhọn của người dùng ngay cả đối với các khối mã 1 dòng.
MetaFight

Câu trả lời:


19

Đúng, bạn chắc chắn đang thiếu một cái gì đó . Gotos thường được sử dụng, như bạn đã nói, để thực hiện chuyển giao quyền kiểm soát một chiều.

Tuy nhiên, các sự kiện không làm điều đó. Khi mã kích hoạt sự kiện, nó biết rõ rằng một khi sự kiện được xuất bản (hoặc được xử lý, xếp hàng, bắn ... vv) sẽ tiếp tục trên dòng tiếp theo trong mã tạo ra sự kiện.

Việc sử dụng goto tạo ra một khớp nối rất chặt chẽ giữa mã gọi câu lệnh đó và mã nằm ở đầu nhận. Nhà phát triển phải có kiến ​​thức sâu sắc về cả hai nơi để sử dụng goto.

Mặt khác, mã kích hoạt các sự kiện thường không biết hoặc không quan tâm ai quan tâm đến việc lắng nghe sự kiện đó. Có thể có một người nghe. Hoặc có thể có 100 người nghe hoặc 0. Những người nghe đó có thể ở trong cùng một chương trình nơi sự kiện được tổ chức, hoặc họ có thể ở một ứng dụng hoàn toàn khác, hoặc họ có thể ở trên một máy khác. Theo như nhà xuất bản có liên quan, ngay khi anh ta tạo ra sự kiện, công việc của anh ta đã hoàn thành.

Nếu bạn ở với tôi cho đến nay, những gì tôi mô tả ở trên là trường hợp lý tưởng của mô hình pub / sub. Thật không may trong thế giới thực, mọi thứ không phải lúc nào cũng lý tưởng và có những trường hợp nhà xuất bản tạo ra một sự kiện, một người đăng ký được gọi, thay đổi toàn bộ trạng thái và đến khi thực thi mã thời gian quay trở lại nhà xuất bản "thế giới" bị đảo lộn. Và tôi chắc chắn rằng bạn đã từng gặp phải điều này trong quá khứ, bởi vì điều kiện này thường xuất hiện khi mô hình pub / sub được triển khai theo cách rất đơn giản (ví dụ: thông qua việc sử dụng các đại biểu hoặc sự kiện trong C # hoặc con trỏ chức năng / giao diện trong C / C ++).

Nhưng vấn đề này không nhất thiết là mẫu pub / sub mà là việc thực hiện nó. Đây là lý do tại sao nhiều hệ thống dựa vào hàng đợi để khi một sự kiện được xuất bản, nó chỉ được xếp hàng để được gọi sau đó cho nhà xuất bản cơ hội hoàn thành việc thực thi trong khi thế giới vẫn còn nguyên vẹn. Khi nhà xuất bản hoàn thành công việc, vòng lặp sự kiện (còn gọi là vòng gửi) sẽ bật ra khỏi các sự kiện và gọi người đăng ký.


+1 xuất bản / đăng ký cho phép khớp nối lỏng lẻo; goto không
Fuhrmanator

6

Có một vài sự khác biệt. Đầu tiên, khi một mã thực thi GOTO, nó sẽ từ bỏ quyền kiểm soát và không có gì đảm bảo rằng nó sẽ lấy lại quyền kiểm soát. Tuy nhiên, một nhà xuất bản trong pub / sub sẽ tiếp tục chạy và thực hiện logic của nó, gửi tin nhắn đi nếu thích hợp. Hành vi của nó là dễ hiểu và có thể dự đoán.

Thứ hai, người đăng ký sẽ nhận được tin nhắn và không giống như GOTO, bản thân tin nhắn mang bối cảnh. Cả loại tin nhắn và bất kỳ thuộc tính nào nó mang theo đều giúp cho người đăng ký thực hiện vai trò của mình. Và, sau khi xử lý một tin nhắn, thuê bao vẫn có thể nhận tin nhắn mới. Vì vậy, đó là hành vi quá dễ hiểu và có thể dự đoán.

Sự khác biệt lớn là nhà xuất bản và người đăng ký có một luồng thực thi được xác định rõ ràng và về bản chất, họ sẽ tiếp tục lặp và thực hiện công việc của mình, trong khi gửi và nhận tin nhắn. Mã với GOTO có thể được viết tốt và có trật tự, nhưng nó cũng có thể xuống cấp và không có sự bảo đảm tương tự đối với hành vi được hiểu rõ ràng.

Bạn nói đúng, mặc dù. Ai đó có thể viết một hệ thống quán rượu / phụ với rất nhiều tin nhắn và rất nhiều bước nhảy nhỏ để theo dõi dòng xử lý có thể trở thành một cơn ác mộng. Mặt khác, bạn có thể viết một hệ thống với các GOTO hoạt động cực kỳ trật tự và dễ hiểu. (Tôi đang nghĩ về mã lắp ráp cho các hệ thống rất phức tạp trước khi các ngôn ngữ tượng trưng chiếm lĩnh.)

Nhưng thông thường, việc tách rời bạn có được từ pub / sub đơn giản hóa vấn đề xử lý phân tán và logic tách rời trong hệ thống của bạn. Thông thường, các GOTO thẳng có xu hướng tạo ra các hệ thống phức tạp trong đó việc hiểu luồng điều khiển trở nên có vấn đề.

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.