Чи використовуються події лише для програмування GUI?


57

Чи використовуються події лише для програмування GUI?

Як ви справляєтесь у звичайному програмі бекенда, коли щось трапляється з цією іншою справою?


6
До речі, джерело подій є повністю ортогональною концепцією програмування подій. Основна концепція пошуку подій полягає в тому, що ви зберігаєте "події" або "зміни" у своїй системі, а не зберігаєте "стан" вашої системи. Наприклад, ви можете змоделювати свій банківський рахунок у вигляді: а) Вашого балансу (ДЕРЖАВНОГО) або б) Серії транзакцій (ПОДІЇ).
ArTs

4
Залежно від використання, "подія", як правило, є лише якоюсь формою зворотного дзвінка, обгорненою цукром. Зворотні виклики звикають скрізь - якщо вам цікаво, це, мабуть, хороше ключове слово для початку пошуку.
J ...

10
Я також зазначу, що навіть якщо ви перейдете на такий низький рівень, як мікроконтролер, ви знайдете апаратні перерви корисною і суперечливо важливою функцією. Відмінно підходить для систем управління, або базового вводу-виводу, як кавоварка. Ці апаратні переривання дійсно не відрізняються від подій.
Dan

Ні! Практичний приклад: події
Nodejs

2
Ви в Windows? Перегляньте переглядач подій. Весело.
Марк.2377,

Відповіді:


106

Ні. Вони дуже зручні для впровадження спостерігачів та переконання, що класи закриті для модифікації.

Скажімо, у нас є метод, який реєструє нових користувачів.

public void Register(user) {
    db.Save(user);
}

Потім хтось вирішує, що електронний лист потрібно надіслати. Ми могли б зробити це:

public void Register(user) {
    db.Save(user);
    emailClient.Send(new RegistrationEmail(user));
}

Але ми щойно змінили клас, який повинен бути закритий для модифікації. Мабуть, добре для цього простого псевдо-коду, але, швидше за все, шлях до божевілля у виробничому коді. Скільки часу, поки цей метод не набере 30 рядків коду, що ледь пов'язане з початковою метою створення нового користувача ??

Набагато приємніше дозволити класу виконувати його основні функціональні можливості та підняти подію, яка розповість, хто слухає, що користувач зареєстрований, і вони можуть вжити будь-яких дій, що потрібно вжити (наприклад, надіслати електронний лист).

public void Register(user) {
    db.Save(user);

    RaiseUserRegisteredEvent(user);
}

Це забезпечує наш код чистим та гнучким. Один з часто недооцінених фрагментів ООП - це те, що класи надсилають повідомлення один одному. Події - це ці повідомлення.


37
Я читаю це і думаю про наш код "створити бронювання" і плачу на деякий час і довго
Сара

1
+1, чудова відповідь. Просто дотичне запитання (це мене трохи хвилювало): чи є особлива причина для того, щоб ви почали свої імена методів (Реєстрація, Збереження та Надсилання) великими літерами? Звичайно, це не впливає на корисність цієї відповіді.
Педро

14
@Hamsteriffic Я в основному розробник C #, і це загальноприйнята умова. Іншої причини немає.
RubberDuck

6
@Hamsterifficмі Крім того, те, що ви називаєте нижчим, але в середині містить великі регістри, часто називається camelCase, тому що в ньому є горбки посередині. Це відрізняє його від snake_case, де рядкові слова розділені підкресленнями, що знайоме пітону та більшості мов оболонок, щоб назвати декілька.
Аарон

5
Я б сказав, що події - це один із типів цих повідомлень. Виклики методів також вважаються передачею повідомлень.
jpmc26

53

Ні.

Класичним прикладом подій, що використовуються в логіці, що не є графічним інтерфейсом, є тригери бази даних.

Тригери - це код, який виконується, коли трапляється певна подія (INSERT, DELETE тощо). Мені це здається подією.

Це визначення події у Вікіпедії:

Під час обчислень подія - це дія чи подія, розпізнана програмним забезпеченням, яке може оброблятися програмним забезпеченням. Комп'ютерні події можуть генеруватися або запускатися системою, користувачем або іншими способами. Зазвичай події обробляються синхронно з потоком програми, тобто програмне забезпечення може мати одне або більше виділених місць, де обробляються події, часто цикл подій. Джерело подій включає користувача, який може взаємодіяти з програмним забезпеченням, наприклад, при натисканні клавіш на клавіатурі. Ще одне джерело - апаратний пристрій, такий як таймер. Програмне забезпечення також може викликати власний набір подій у циклі подій, наприклад, щоб повідомити про виконання завдання. Програмне забезпечення, яке змінює свою поведінку у відповідь на події, як вважається, керується подіями, часто з метою інтерактивності.

Не всі події створюються користувачем. Деякі з них генеруються таймером, як кронтаб, бази даних INSERT, як я згадував раніше.

У цьому визначенні також зазначено, що деякі програми або системи "керовані подіями, часто з метою інтерактивності" , з чого можна дійти висновку, що мета або корисність подій є не виключно, а досить часто для забезпечення інтерактивності (як GUI) хоча це не обов'язково графічні інтерфейси, оскільки програми CLI також можуть бути інтерактивними).


2
Я завжди думаю про це, коли чую про тригери бази даних: thecodelesscode.com/case/42
Алмо

Як колишній розробник DBA, який зараз розробляється, я призиваюся кожен раз, коли чую, як люди говорять про використання тригерів, не враховуючи ширшої продуктивності БД.
Три логіки цінності

28

Програмування на основі подій фактично також використовується для високоефективних програмувань сервера.

При типовому навантаженні сервера значна частина часу на обробку результату фактично відбувається з вводу / виводу. Наприклад, витяг даних з (7200 RPM) жорсткого диска може зайняти до 8,3 мс. Для сучасного процесора ГГц це може дорівнювати ~ 1 млн тактових циклів. Якби процесор чекав даних кожен раз (нічого не роблячи), ми втратили б багато циклів годин.

Традиційні методи програмування обходять це шляхом введення декількох потоків . Процесор намагається одночасно запускати сотні потоків. Однак проблема цієї моделі полягає в тому, що кожного разу, коли процесор перемикає потік, йому потрібно сотні тактових циклів, щоб переключитися на контекст . Контекстний перемикач - це коли процесор копіює локальну пам'ять потоку в регістри процесора, а також зберігає реєстр / стан старого потоку в оперативну пам'ять.

Крім того, кожен потік повинен використовувати певний об'єм пам'яті для зберігання свого стану.

Сьогодні відбувся поштовх для серверів, які мають єдиний потік, який працює в циклі. Потім твори висуваються на насос повідомлення , який виконує функцію черги для одного потоку (подібно до потоку інтерфейсу користувача). Замість того, щоб чекати, коли робота закінчиться, процесор встановлює подію зворотного дзвінка для таких речей, як доступ до жорсткого диска. Що зменшує переключення контексту.

Найкращим прикладом такого сервера є Node.js , для якого було показано, що він може обробляти 1 мільйон одночасних з'єднань зі скромним обладнанням, тоді як сервер Java / Tomcat би боровся на кілька тисяч.


2
"Скромна апаратура" трохи вводить в оману. Вам буде потрібно 8 ГБ + для Node, крім того, що використовується в ОС. І якщо у вас стільки пам’яті, Tomcat може легко обробити кілька тисяч підключень. Зрозуміло, є велика різниця, але це не 1000x.
Пол Дрейпер

@PaulDraper ні, не може. І ні це не робить. Вам потрібно 8 Гб + лише стік на 8000 ниток. Це велика різниця.
ArTs

3
@PaulDraper окрім 8 ГБ дуже скромний за стандартами сервера. Я працював на машинах із 128 ГБ оперативної пам’яті, і вони навіть не завантажені повністю. Баранчикові палички коштують дорожче, ніж уся ваша машина.
ArTs

це залежить від вашого розміру стека. На більшості платформ Oracle / OpenJDK за замовчуванням дорівнює 1 Мбайт для 64-розрядних, а для 32-бітових - 512 Кб. Якщо ви просто приймете значення за замовчуванням, ви будете правильно. Але за замовчуванням - це не те, як ви потрапляєте до підключень до вузла 1M;) У будь-якому випадку, 128K достатньо; ви можете піти ще менше. Це було б 1 ГБ місця для стека для 8000 потоків.
Пол Дрейпер

6
Ви помиляєтесь. Навіть із типовим розміром стека вам потрібно лише 8 Гб віртуальної пам'яті. Пам'ять фіксується на льоту за потребою. Зазвичай вам потрібна лише одна сторінка на стек, якщо ви фактично не використовуєте додаткову пам'ять. І на практиці більшість потоків у такій системі мають лише ті (зазвичай) стеки на 64 кіБ. Використання віртуальної пам'яті - це велика справа в 32-розрядної ОС, але не стільки в 64-розрядної. Ви натрапляєте на інші межі набагато швидше - наприклад, виснаження портів TCP, наприклад :) А де ви думаєте, де зберігаються ці "псевдосклади" вузла? Правильно, на купі.
Луань

10

Події також широко використовуються в мережевому програмуванні (наприклад, Nginx), щоб уникнути дорогих циклів очікування зайнятості, а натомість забезпечити чистий інтерфейс, щоб точно знати , коли є певна операція (введення / виведення, термінові дані тощо). Це також є вирішенням проблеми C10k .

Основна ідея - забезпечити ОС набором розеток (тобто мережевих з'єднань) для моніторингу подій, усіх із них або лише деяких, які вас особливо цікавлять (наприклад, дані, доступні для читання); коли така активність виявиться операційною системою в одному з сокетів у списку, ви отримаєте сповіщення про подію, яку ви шукали за допомогою API, після чого вам доведеться розібратися, звідки вона походить, і діяти відповідно .

Тепер це низький і абстрактний погляд, а ще складніше, щоб добре досягти масштабу. Однак є безліч фреймворків вищого рівня, які займаються цим рівномірно на платформі: мені приходять в голову Twisted for Python, Boost.Asio для C ++ або libevent для C.


+1 "дорогі петлі зайнятого очікування": іншими словами, це корисно в будь-яких паралельних процесах, які передбачають деяку бездіяльність (очікування), а також синхронізацію між такими процесами (повідомленнями або подіями). Як багато справжнього світу працює.
fr13d

Цікаво з’ясувати, що розетки спочатку були розроблені як форма IPC на одній машині до того, як існували мережі.

5

Вбудовані системи майже завжди притаманні подій, навіть якщо вони не запрограмовані явно як такі.

Ці події відбуваються з таких речей, як апаратне переривання, натискання кнопок, аналогово-цифрові показання періоду, закінчення таймера тощо

Вбудовані системи з низькою потужністю ще більше схильні до подій; вони проводять більшу частину часу уві сні (процесор спить у режимі низької потужності), чекаючи, що щось станеться (що "щось" - це подія).

Однією з найпоширеніших і популярних рамок вбудованих систем, керованих подіями, є Quantum Platform (QP) (QP також працює під Linux, Windows та будь-якою unix-подібною ОС.) Державні машини є природним пристосуванням для програмування, керованого подіями, оскільки програма не є "послідовною" у типовому сенсі, скоріше, це набір "зворотних зворотів", які викликаються залежно від стану системи та поточної події.


3

Повідомлення подій Грегор Хопе.

Архітектури, керовані подією Грегор Хопе.

Архітектура SEDA , валлійська, куллер, пивовар.

як ти справляєшся у звичайному програмі бекенда, коли щось трапляється, роби щось інше?

Кінцева державна машина - це один загальний підхід

Given(State.A)
When(Event.B)
Then(State.C)
    .and(Consequences.D)

2
1, це насправді не є узгодженою відповіддю, а 2, FSM - не гарні приклади використання подій.
whatsisname

1
ЧСМ. Я впевнений, що релігія пастафарів спостерігає за низкою подій ;-)
fr13d

0

У вбудованих системах події відбуваються під час перерв. Існує багато джерел переривань, від таймерів до вводу-виводу.

Також у RTOS можуть бути події. Один приклад - очікування повідомлення з іншого завдання.


0

Для невбудованої системи, але те, що я робив у C #, була система SCADA. Було багато подій, пов’язаних із тим, що відбувалося на складі, коли завантаження було вивантажено частиною події, що генерується системою, а інша частина записувала новий стан у базу даних. У нас, звичайно, був якийсь клієнт GUI, але це було просто показати стан бази даних, що відображало стан складу. Таким чином, це було серверне програмне забезпечення на основі подій та потоків. Досить складно розвиватися.

https://en.wikipedia.org/wiki/SCADA

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.