Có phải các sự kiện chỉ được sử dụng cho lập trình GUI?
Làm thế nào để bạn xử lý trong lập trình phụ trợ bình thường khi một cái gì đó xảy ra với điều này khác?
Có phải các sự kiện chỉ được sử dụng cho lập trình GUI?
Làm thế nào để bạn xử lý trong lập trình phụ trợ bình thường khi một cái gì đó xảy ra với điều này khác?
Câu trả lời:
Không. Chúng thực sự tiện dụng để triển khai Trình quan sát và đảm bảo rằng các lớp được đóng để sửa đổi.
Giả sử chúng ta có một phương thức đăng ký người dùng mới.
public void Register(user) {
db.Save(user);
}
Sau đó, một người nào đó quyết định rằng một email nên được gửi. Chúng ta có thể làm điều này:
public void Register(user) {
db.Save(user);
emailClient.Send(new RegistrationEmail(user));
}
Nhưng chúng tôi vừa sửa đổi một lớp được cho là đã đóng để sửa đổi. Có lẽ tốt cho mã giả đơn giản này, nhưng có thể là cách để điên rồ trong mã sản xuất. Mất bao lâu cho đến khi phương thức này là 30 dòng mã mà hầu như không liên quan đến mục đích ban đầu là tạo người dùng mới ??
Sẽ tốt hơn nhiều khi để lớp thực hiện chức năng cốt lõi của nó và đưa ra một sự kiện cho biết bất cứ ai đang nghe rằng người dùng đã đăng ký và họ có thể thực hiện bất kỳ hành động nào họ cần thực hiện (chẳng hạn như gửi email).
public void Register(user) {
db.Save(user);
RaiseUserRegisteredEvent(user);
}
Điều này giữ cho mã của chúng tôi sạch sẽ và linh hoạt. Một trong những phần thường bị bỏ qua của OOP là các lớp gửi tin nhắn cho nhau. Sự kiện là những tin nhắn.
Không.
Một ví dụ kinh điển về các sự kiện đang được sử dụng trong logic phi GUI là các trình kích hoạt cơ sở dữ liệu.
Kích hoạt là mã được thực thi khi một sự kiện nhất định xảy ra (CHERTN, XÓA, v.v.). Có vẻ như một sự kiện với tôi.
Đây là định nghĩa Wikipedia về sự kiện:
Trong điện toán, một sự kiện là một hành động hoặc sự cố được công nhận bởi phần mềm có thể được xử lý bởi phần mềm. Các sự kiện máy tính có thể được tạo hoặc kích hoạt bởi hệ thống, bởi người dùng hoặc theo những cách khác. Thông thường, các sự kiện được xử lý đồng bộ với luồng chương trình, nghĩa là phần mềm có thể có một hoặc nhiều nơi dành riêng cho các sự kiện được xử lý, thường là một vòng lặp sự kiện. Một nguồn sự kiện bao gồm người dùng, người có thể tương tác với phần mềm bằng cách, ví dụ, tổ hợp phím trên bàn phím. Một nguồn khác là một thiết bị phần cứng như bộ đếm thời gian. Phần mềm cũng có thể kích hoạt tập hợp các sự kiện của riêng nó vào vòng lặp sự kiện, ví dụ để truyền đạt việc hoàn thành một nhiệm vụ. Phần mềm thay đổi hành vi của nó để đáp ứng với các sự kiện được cho là hướng đến sự kiện, thường với mục tiêu là tương tác.
Không phải tất cả các sự kiện là do người dùng tạo ra. Một số được tạo bởi một bộ đếm thời gian như một crontab của cơ sở dữ liệu INSERT như tôi đã đề cập trước đó.
Định nghĩa cũng nêu rõ hơn một số chương trình hoặc hệ thống là "hướng sự kiện, thường với mục tiêu là tương tác" , từ đó người ta có thể rút ra rằng mục đích hoặc tính hữu ích của các sự kiện không chỉ, mà thường là, để cung cấp tính tương tác (như GUI mặc dù không nhất thiết phải là GUI, vì các chương trình CLI cũng có thể tương tác).
Lập trình dựa trên sự kiện thực sự cũng được sử dụng cho lập trình máy chủ có hiệu suất cao.
Ở một khối lượng công việc máy chủ thông thường, phần lớn thời gian xử lý một kết quả thực sự đến từ I / O. Ví dụ, kéo dữ liệu ra khỏi ổ đĩa cứng (7200 RPM) có thể mất tới 8,3 ms. Đối với bộ xử lý GHz hiện đại, điều đó sẽ tương đương với ~ 1 triệu chu kỳ xung nhịp. Nếu CPU phải đợi dữ liệu mỗi lần (không làm gì), chúng ta sẽ mất rất nhiều chu kỳ xung nhịp.
Các kỹ thuật lập trình truyền thống có được xung quanh điều này bằng cách giới thiệu nhiều chủ đề . CPU cố gắng chạy hàng trăm luồng đồng thời. Tuy nhiên, vấn đề mà mô hình này là, mỗi lần CPU chuyển luồng, nó đòi hỏi hàng trăm chu kỳ xung nhịp để chuyển đổi ngữ cảnh . Chuyển đổi ngữ cảnh là khi CPU sao chép bộ nhớ cục bộ của luồng vào các thanh ghi của CPU và cũng lưu trữ thanh ghi / trạng thái của luồng cũ vào RAM.
Ngoài ra, mỗi luồng phải sử dụng một lượng bộ nhớ nhất định để lưu trữ trạng thái của nó.
Ngày nay, đã có một sự thúc đẩy cho các máy chủ có một luồng duy nhất, chạy trong một vòng lặp. Sau đó, các phần công việc được đẩy lên một bơm thông báo , hoạt động như một hàng đợi cho một luồng (giống như trên một luồng UI). Thay vì chờ công việc kết thúc, CPU sẽ đặt một sự kiện gọi lại, cho những thứ như truy cập ổ đĩa cứng. Làm giảm chuyển đổi ngữ cảnh.
Ví dụ tốt nhất về một máy chủ như vậy là Node.js , được chứng minh là có thể xử lý 1 triệu kết nối đồng thời với phần cứng khiêm tốn, trong khi máy chủ Java / Tomcat sẽ gặp khó khăn ở mức vài nghìn.
Các sự kiện cũng được sử dụng nhiều trong lập trình mạng (ví dụ Nginx) để tránh các vòng lặp bận rộn đắt tiền và thay vào đó cung cấp giao diện sạch để biết chính xác khi nào có một hoạt động nhất định (I / O, dữ liệu khẩn cấp, v.v.). Đây cũng là một giải pháp cho vấn đề C10k .
Ý tưởng cơ bản là cung cấp cho HĐH một bộ ổ cắm (ví dụ: kết nối mạng) để theo dõi các sự kiện, tất cả chúng hoặc chỉ một số bạn đặc biệt quan tâm (ví dụ: dữ liệu có sẵn để đọc); Khi hệ điều hành được phát hiện bởi một trong các ổ cắm trong danh sách, bạn sẽ nhận được thông báo về sự kiện mà bạn đang tìm kiếm bởi API, sau đó bạn sẽ phải sắp xếp nó đến từ đâu và hành động phù hợp .
Bây giờ, đây là một cái nhìn cấp thấp và trừu tượng, hơn nữa khó khăn để có được quy mô tốt. Tuy nhiên, có rất nhiều khung công tác cấp cao hơn giải quyết vấn đề đó theo kiểu đa nền tảng: Twisted for Python, Boost.Asio cho C ++ hoặc libevent cho C xuất hiện trong tâm trí tôi.
Các hệ thống nhúng hầu như luôn luôn hướng đến sự kiện, ngay cả khi chúng không được lập trình rõ ràng như vậy.
Những sự kiện này đến từ những thứ như gián đoạn phần cứng, nhấn nút, đọc thời gian tương tự sang số, hết hạn hẹn giờ, v.v.
Các hệ thống nhúng công suất thấp thậm chí có nhiều khả năng được điều khiển theo sự kiện; họ dành phần lớn thời gian để ngủ (CPU ngủ ở chế độ năng lượng thấp), chờ đợi điều gì đó xảy ra ("cái gì đó" là một sự kiện).
Một trong những khung phổ biến và phổ biến nhất cho các hệ thống nhúng theo hướng sự kiện là Nền tảng lượng tử (QP) (QP cũng hoạt động trong Linux, Windows và bất kỳ HĐH nào giống như máy chủ.) vì chương trình không phải là "tuần tự" theo nghĩa thông thường, thay vào đó, nó là một tập hợp các "cuộc gọi lại" được gọi tùy thuộc vào trạng thái hệ thống và sự kiện hiện tại.
Tin nhắn sự kiện Gregor Hohpe.
Kiến trúc hướng sự kiện Gregor Hohpe.
Kiến trúc SEDA , tiếng Wales, Culler, nhà sản xuất bia.
Làm thế nào để bạn xử lý trong lập trình phụ trợ bình thường khi một cái gì đó xảy ra làm điều này khác?
Máy trạng thái hữu hạn là một cách tiếp cận phổ biến
Given(State.A)
When(Event.B)
Then(State.C)
.and(Consequences.D)
Trong các hệ thống nhúng, các sự kiện xảy ra trong quá trình ngắt. Có nhiều nguồn ngắt, từ bộ định thời đến I / O.
Ngoài ra, RTOS cũng có thể có các sự kiện. Một ví dụ là chờ tin nhắn từ một nhiệm vụ khác.
Đối với hệ thống không nhúng nhưng thứ tôi đang làm trong C # là hệ thống SCADA. Có nhiều sự kiện liên quan đến những gì đã xảy ra trong kho khi tải được tải một phần của sự kiện do hệ thống tạo ra và phần khác đang ghi trạng thái mới vào cơ sở dữ liệu. Tất nhiên chúng tôi có một số máy khách GUI nhưng nó chỉ hiển thị trạng thái của cơ sở dữ liệu phản ánh trạng thái của kho. Vì vậy, nó là phần mềm máy chủ phụ trợ dựa trên các sự kiện và phân luồng. Khá thách thức để phát triển.