Đầu tiên, tớ rất ngưỡng mộ công sức tìm hiểu và cách đặt câu hỏi của cậu. Việc tìm hiểu và đưa ra câu hỏi như vậy rất có ích, dù sau này cậu làm bất cứ nghề gì. Keep it up!
Tớ không rõ cậu đã tìm thấy câu trả lời mà cậu mong muốn chưa, nên tớ sẽ thử trả lời cho cậu nhé!
Event-driven programming là gì?
Cháu muốn hỏi là lập trình hướng sự kiện là gì? lập trình hướng sự kiện có gì khác so với các paradigm lập trình khác (cháu cũng không biết rõ nên so sánh với cái gì, có thể là OOP, functional programming, …)
Về định nghĩa Event-driven programming, cậu có thể tham khảo comment của @doanguyen.
Một cách đơn giản, cậu có thể hiểu Event-driven programming là mô thức hướng tới việc xây dựng hệ thống phản ứng lại các sự kiện bên ngoài trong 1 khoảng thời gian ngắn. Chẳng hạn:
- Một phần mềm có giao diện phản ứng lại các tương tác từ người dùng.
- Một website phản ứng lại các sự kiện gửi request từ client.
- Một hệ thống realtime phản ứng lại các sự kiện thu được qua các sensor.
- Etc.
Tớ đoán cậu sẽ thắc mắc “hệ thống nào chẳng phản ứng với sự kiện bên ngoài?”. Không hẳn là vậy đâu Cậu có thể có các phần mềm được kích hoạt để chạy tại một thời điểm, và tắt đi sau khi xong việc, mà không phản ứng với sự kiện gì. Script, batch,… là những phần mềm như vậy.
Event-driven programming khác gì với các mô thức khác?
Cậu có thể thấy rõ Event-driven programming được dùng để giải quyết vấn đề hoàn toàn khác với các mô thức lập trình khác.
- Event-driven programming là mô thức giải quyết vấn đề “phản ứng” lại một “sự kiện” nào đó. Nền tảng hỗ trợ mô thức này sẽ đảm bảo cho cậu cơ chế để kết nối “sự kiện” và “phản ứng thích hợp” (cơ chế này là “thế lực vô hình” mà cậu băn khoăn. Tớ sẽ nói rõ nó hơn ở đoạn sau).
- Object-oriented programming hướng tới việc cậu tổ chức chương trình thành các đối tượng một cách logic, với các hành vi và dữ liệu mà nó có. Điều này đặc biệt có lợi khi cậu có lượng code lớn trong project.
- Functional programming hướng tới việc trừu tượng hóa quá trình dữ liệu thay đổi qua các bước. Nó đặc biệt hữu dụng khi cậu có một process phức tạp để xử lý dữ liệu, khi đó cậu không phải viết quá nhiều code để đạt được mục đích của mình => code của cậu dễ đọc và hiểu hơn rất nhiều.
- Procedural programming (Pascal của cậu thuộc loại này) hướng tới việc chia nhỏ chương trình của cậu thành các procedure/sub routine. Kết hợp tất cả lại sẽ cho cậu một chương trình hoàn chỉnh.
Tớ không phải đề cập tới lợi ích của nó nữa nhỉ, nó tương đối tự nhiên mà?
Cậu thấy đó, mỗi mô thức lập trình hướng tới việc giải quyết vấn đề khác nhau.
Điều đó đồng nghĩa với việc, nếu chương trình của cậu lớn, có “phản ứng” lại các sự kiện, có việc xử lý dữ liệu qua nhiều bước, thì cậu hoàn toàn có thể áp dụng cả 3 mô thức Event-driven programming, Object-oriented programming, và Functional programming để hoàn thành chương trình của cậu.
Chương trình event-driven programming
Cháu có đoạn code ngắn viết bằng lua như này không biết là giống kiểu lập trình hướng sự kiện chưa?..
Đoạn code trên cho thấy cậu hiểu cách tạo ra 1 chương trình sử dụng mô thức event-driven programming rồi đó.
Mô thức này đúng là có 1 vòng lặp vô hạn, với vai trò lắng nghe sự kiện, và một đoạn code để xử lý/phản ứng lại sự kiện đó. Tuy nhiên, cậu có thể thấy một vài điểm đáng chú ý:
- Vòng lặp vô hạn, lắng nghe sự kiện là quy chuẩn chung cho tất cả các chương trình áp dụng EDP.
Vậy nên, thường các framework support cho cậu phần này rồi, cậu không phải viết lại vòng lặp nữa. Framework cũng sẽ cho cậu một người phân phối sự kiện, để đảm bảo một sự kiện bất kỳ sẽ được kết nối với đúng thành phần xử lý nó. Cậu chỉ cần khai báo “kiểu sự kiện gì” và “ai xử lý sự kiện đó”, framework sẽ giúp cậu làm phần khó khăn hơn đó.
Đó là “thế lực vô hình” mà cậu cảm thấy, nhưng chưa sờ vào đấy!
- Chương trình của cậu chỉ phản ứng với 1 loại event duy nhất (nhập từ bàn phím), và phản ứng với nó theo 1 cách duy nhất (in ra màn hình). Cậu không có cách nào phản ứng thêm với các loại event khác, hay phản ứng theo 1 cách khác, mà không phải sửa vòng lặp chính.
Một framework EDP sẽ thường sẽ hỗ trợ cậu khả năng xử lý nhiều loại event khác nhau, và cho phép cậu định nghĩa các logic xử lý cho từng loại event, mà không phải sửa vòng lặp chính.
Mọi framework EDP đều có một thành phần gọi là event dispatcher. Anh bạn này có trách nhiệm phân phối event tới thành phần có trách nhiệm xử lý/tiêu thụ event đó (có thể là 1 thread nào đó, hoặc một đoạn code nào đó). Event dispatcher cũng là nơi quyết định các event được phân bố thế nào (cậu có thể broadcasting event tới nhiều thành phần, hay đưa nó tới 1 thành phần xác định thôi).
Đó là thứ cậu không có trong đoạn code của cậu
Cậu có thể đoán được lý do sao cậu không code thế này:
chương trình main chính/
├─ code xử lý khi user ấn phím
├─ code xử lý khi user di chuột
├─ code N
Lý do tớ đã đề cập, EPD hướng tới việc tạo ra 1 framework để cậu chỉ cần định nghĩa loại sự kiện cậu muốn xử lý, và cách xử lý sự kiện đó. Cậu không cần phải quan tâm, hay sửa vòng lặp chính để làm điều này, nên code của cậu lúc đó sẽ rất dễ bảo trì, đơn giản để viết và dễ hiểu.
Tớ hi vọng cậu đã hiểu thêm về EDP qua bài viết rất dài này. Tớ rất muốn trả lời câu hỏi này sớm hơn, nhưng vì thời gian không cho phép, nên bây giờ tớ mới có thời gian hoàn thiện câu trả lời. Hi vọn nó không quá trễ