Lập trình hướng sự kiện: khi nào nó có giá trị?


19

Ok, tôi biết tiêu đề của câu hỏi này gần giống với Khi tôi nên sử dụng lập trình dựa trên sự kiện? nhưng câu trả lời của câu hỏi đã không giúp tôi quyết định liệu tôi có nên sử dụng các sự kiện trong trường hợp cụ thể mà tôi đang đối mặt hay không.

Tôi đang phát triển một ứng dụng nhỏ. Đây là một ứng dụng đơn giản và phần lớn chức năng của nó là CRUD cơ bản.

Theo các sự kiện nhất định (khi sửa đổi dữ liệu nhất định), ứng dụng phải ghi một bản sao cục bộ của dữ liệu đã nói vào một tệp. Tôi không chắc chắn về cách tốt nhất để thực hiện điều này. Tôi có thể:

  • Sự kiện cháy khi dữ liệu được sửa đổi và liên kết một phản hồi (tạo tệp) với các sự kiện đó. Ngoài ra, thực hiện các mẫu quan sát. Điều đó có vẻ như phức tạp không cần thiết.
  • Gọi mã tạo tệp trực tiếp từ mã sửa đổi dữ liệu. Đơn giản hơn nhiều, nhưng có vẻ sai là sự phụ thuộc phải theo cách này, nghĩa là có vẻ sai khi chức năng cốt lõi của ứng dụng (mã sửa đổi dữ liệu) phải được ghép với perk thêm đó (mã tạo tệp sao lưu). Tuy nhiên, tôi biết rằng ứng dụng này sẽ không phát triển đến điểm mà việc ghép nối đó gây ra vấn đề.

Cách tiếp cận tốt nhất trong trường hợp này là gì?


2
Tôi muốn nói rằng đừng tự mình thực hiện bất cứ điều gì - chỉ cần sử dụng xe buýt sự kiện hiện có. Điều này sẽ làm cho cuộc sống đơn giản hơn nhiều ...
Boris the Spider

Lập trình hướng sự kiện vốn không đồng bộ. Các sự kiện có thể hoặc không thể đi qua, theo thứ tự bạn dự định hoặc có thể theo thứ tự khác hoặc hoàn toàn không. Nếu bạn có thể đối phó với sự phức tạp thêm đó, hãy đi cho nó.
Pieter B

Điều khiển theo sự kiện thường có nghĩa là mã của bạn được cung cấp dưới dạng gọi lại và chúng được gọi từ nơi khác theo cách bạn không thể dự đoán. Mô tả của bạn nghe có vẻ giống như vậy khi một cái gì đó cụ thể xảy ra trong mã của bạn, bạn cần phải làm nhiều hơn một triển khai ngây thơ sẽ yêu cầu. Chỉ cần mã các cuộc gọi thêm vào.
Thorbjørn Ravn Andersen

một sự khác biệt giữa sự kiện-driven và dựa trên sự kiện. Xem ví dụ podcast podcast .NET Rocks rất kích thích tư duy tập 355 với Ted Faison, Ted Faison đưa các sự kiện đến giới hạn! ( URL tải xuống trực tiếp ) và cuốn sách Lập trình dựa trên sự kiện: đưa các sự kiện đến giới hạn .
Peter Mortensen

Cuộc phỏng vấn với Ted Faison bắt đầu lúc 13 phút 10 giây.
Peter Mortensen

Câu trả lời:


31

Thực hiện theo nguyên tắc KISS: Giữ cho nó đơn giản, ngu ngốc hoặc nguyên tắc YAGNI: Bạn sẽ không cần nó.

Bạn có thể viết mã như:

void updateSpecialData() {
    // do the update.
    backupData();
}

Hoặc bạn có thể viết mã như:

void updateSpecialData() {
     // do the update.
     emit SpecialDataUpdated();
}

void SpecialDataUpdatedHandler() {
     backupData();
}

void configureEventHandlers() {
     connect(SpecialDataUpdate, SpecialDataUpdatedHandler);
}

Trong trường hợp không có lý do thuyết phục để làm khác, hãy làm theo lộ trình đơn giản hơn. Các kỹ thuật như xử lý sự kiện rất mạnh mẽ, nhưng chúng làm tăng độ phức tạp của mã của bạn. Nó đòi hỏi nhiều mã hơn để làm việc và nó làm cho những gì xảy ra trong mã của bạn khó theo dõi hơn.

Các sự kiện rất quan trọng trong tình huống phù hợp (hãy tưởng tượng bạn đang cố gắng lập trình UI mà không có sự kiện!) Nhưng đừng sử dụng chúng khi bạn có thể KISS hoặc YAGNI thay thế.


Tôi đặc biệt thích việc bạn đề cập rằng các sự kiện bắn khi dữ liệu bị thay đổi không phải là chuyện nhỏ.
NoChance

13

Ví dụ bạn mô tả về một dữ liệu đơn giản, trong đó sửa đổi kích hoạt một số hiệu ứng hoàn toàn có thể được thực hiện với mẫu thiết kế quan sát viên :

  • điều này đơn giản để thực hiện và duy trì hơn mã hướng sự kiện đầy đủ.
  • sự kết hợp giữa chủ thể và người quan sát có thể trừu tượng, tạo điều kiện phân tách các mối quan tâm.
  • đó là lý tưởng cho một đến nhiều mối quan hệ (đối tượng có một hoặc nhiều người quan sát).

Cách tiếp cận hướng sự kiện đáng để đầu tư cho các kịch bản phức tạp hơn, khi nhiều tương tác khác nhau có thể xảy ra, trong bối cảnh nhiều-nhiều hoặc nếu các phản ứng dây chuyền được dự kiến ​​(ví dụ, một đối tượng thông báo cho người quan sát, trong một số trường hợp muốn sửa đổi môn học hoặc môn học khác)


1
Tôi bối rối, không phải là người quan sát chỉ là một cách để thực hiện các sự kiện?
Svick 13/03/2016

1
@svick Mình không nghĩ vậy. Trong lập trình hướng sự kiện, bạn có một vòng lặp chính xử lý các sự kiện trong nhiều mối quan hệ, với người gửi và người quan sát tách rời. Tôi nghĩ rằng người quan sát có thể đóng góp bằng cách xử lý một loại sự kiện vuông góc, nhưng bạn không thể đạt được toàn bộ phổ EDP chỉ với một người quan sát. Tôi nghĩ rằng sự nhầm lẫn xuất phát từ thực tế là trong phần mềm kiện điều khiển, quan sát đôi khi được thực hiện trên đỉnh của xử lý sự kiện (thường là MVC với một GUI)
Christophe

5

Như bạn nói, các sự kiện là một công cụ tuyệt vời để giảm sự ghép nối giữa các lớp; Vì vậy, trong khi nó có thể liên quan đến việc viết mã bổ sung bằng một số ngôn ngữ mà không có hỗ trợ tích hợp cho các sự kiện, nó làm giảm sự phức tạp của bức tranh lớn.

Các sự kiện được cho là một trong những công cụ quan trọng nhất trong OO (Theo Alan Kay - Đối tượng giao tiếp bằng cách gửi và nhận tin nhắn ). Nếu bạn sử dụng một ngôn ngữ có hỗ trợ tích hợp cho các sự kiện hoặc coi các chức năng là công dân hạng nhất, thì việc sử dụng chúng là không có trí tuệ.

Ngay cả trong các ngôn ngữ không có hỗ trợ tích hợp, số lượng soạn sẵn cho một cái gì đó giống như mẫu Observer là khá nhỏ. Bạn có thể tìm thấy một thư viện sự kiện chung chung ở đâu đó mà bạn có thể sử dụng trong tất cả các ứng dụng của mình để giảm thiểu bản tóm tắt. (Một trình tổng hợp sự kiện chung hoặc hòa giải sự kiện là hữu ích trong hầu hết mọi loại ứng dụng).

Có đáng giá trong một ứng dụng nhỏ? Tôi chắc chắn sẽ nói .

  • Giữ các lớp tách rời nhau giữ cho biểu đồ phụ thuộc lớp của bạn sạch sẽ.
  • Các lớp không có bất kỳ phụ thuộc cụ thể nào có thể được kiểm tra riêng rẽ mà không cần xem xét cho các lớp khác trong các thử nghiệm.
  • Các lớp không có bất kỳ phụ thuộc cụ thể nào yêu cầu ít bài kiểm tra đơn vị hơn để bảo hiểm hoàn chỉnh.

Nếu bạn đang nghĩ "Ồ nhưng nó thực sự chỉ là một ứng dụng rất nhỏ, nó không thực sự quan trọng đến thế" , hãy xem xét:

  • Các ứng dụng nhỏ đôi khi cuối cùng được kết hợp với các ứng dụng lớn hơn sau này.
  • Các ứng dụng nhỏ có thể bao gồm ít nhất một số logic hoặc thành phần mà sau này có thể cần được sử dụng lại trong các ứng dụng khác.
  • Các yêu cầu cho các ứng dụng nhỏ có thể thay đổi, khiến nhu cầu cấu trúc lại, dễ dàng hơn khi mã hiện tại được tách rời.
  • Các tính năng bổ sung có thể được thêm vào sau đó, nhắc nhở cần phải mở rộng mã hiện tại, điều này cũng dễ dàng hơn nhiều khi mã hiện tại đã được tách rời.
  • Mã được ghép lỏng lẻo thường không mất nhiều thời gian để viết hơn mã được ghép chặt chẽ; nhưng mã được ghép chặt chẽ mất nhiều thời gian hơn để cấu trúc lại và kiểm tra so với mã được ghép lỏng lẻo.

Nhìn chung, kích thước của một ứng dụng không phải là một yếu tố quyết định trong việc có nên giữ các lớp liên kết lỏng lẻo hay không; Nguyên tắc RẮN không chỉ dành cho các ứng dụng lớn, chúng áp dụng cho phần mềm và cơ sở mã ở mọi quy mô.

Trong thực tế, thời gian được lưu trong đơn vị kiểm tra các lớp được ghép lỏng lẻo của bạn trong sự cô lập sẽ cân bằng với bất kỳ thời gian bổ sung nào dành cho việc tách rời các lớp đó.


2

Mẫu quan sát có thể được triển khai theo kiểu nhỏ hơn nhiều so với bài viết Wikipedia (hoặc sách GOF) mô tả nó, giả sử ngôn ngữ lập trình của bạn hỗ trợ một cái gì đó như "cuộc gọi lại" hoặc "đại biểu". Chỉ cần chuyển một phương thức gọi lại vào mã CRUD của bạn (phương thức quan sát viên, có thể là phương thức "ghi vào tệp" chung hoặc là một phương thức trống). Thay vì "bắn sự kiện", chỉ cần gọi lại.

Mã kết quả sẽ chỉ phức tạp tối thiểu hơn so với việc gọi trực tiếp mã tạo tệp, nhưng không có nhược điểm của việc ghép chặt các thành phần không liên quan.

Điều đó sẽ mang lại cho bạn "tốt nhất của cả hai thế giới", mà không phải hy sinh việc tách rời cho "YAGNI".


Nó hoạt động ngay lần đầu tiên Doc, nhưng khi sự kiện cần kích hoạt điều thứ hai, có khả năng lớp sẽ cần phải được sửa đổi theo cách này. Nếu bạn sử dụng mẫu quan sát viên, bạn có thể thêm bao nhiêu hành vi mới mà bạn muốn mà không cần mở lớp gốc sao lưu để sửa đổi.
RubberDuck

2
@RubberDuck: OP đang tìm kiếm một giải pháp "tránh sự phức tạp không cần thiết" - nếu có các sự kiện / hành vi khác nhau cần thiết, có lẽ anh ta sẽ không coi mô hình quan sát là quá phức tạp. Vì vậy, tôi đồng ý với những gì bạn nói, khi mọi thứ trở nên phức tạp hơn, một người quan sát đầy đủ sẽ phục vụ anh ta tốt hơn, nhưng chỉ sau đó.
Doc Brown

Một tuyên bố công bằng, nhưng nó cảm thấy như một cửa sổ bị phá vỡ đối với tôi.
RubberDuck

2
@RubberDuck: thêm một người quan sát đầy đủ, với cơ chế của nhà xuất bản / người đăng ký "chỉ trong trường hợp", khi không thực sự cần thiết, tôi cảm thấy như bị áp đảo - điều đó không tốt hơn.
Doc Brown

1
Tôi không đồng ý rằng nó có thể vượt qua kỹ thuật. Tôi có lẽ cảm thấy cách tôi làm bởi vì nó tầm thường để thực hiện trong chồng lựa chọn của tôi. Dù sao, chúng tôi sẽ chỉ đồng ý không đồng ý?
RubberDuck
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.