Обычно я решаю это с помощью чего-то вроде:
task = _taskProvider.getNextFromQueue();
if (task.id == TaskExecutor.TasksEnum.One) {
_taskExecutor.executeTaskOne();
return;
} else if (task.id == TaskExecutor.TasksEnum.Two) {
_taskExecutor.executeTaskTwo();
return;
} else if (task.id == TaskExecutor.TasksEnum.Three) {
_taskExecutor.executeTaskThree();
return;
}
//and so on...
Я мог бы переключить if-else
на switch
при необходимости.
Я верю, что существует лучший способ реализовать подобный код.
Одна вещь, которая приходит на ум, - это использовать таблицу (карту) для хранения идентификаторов задач и указателей на соответствующие функции, но я не уверен, что это полезно и обеспечивает адекватную производительность.
Еще одна вещь, которая меня беспокоит, это механизм уведомлений. Эта проблема возникает, когда TaskProvider
и TaskExecutor
являются двумя отдельными объектами, которые работают в разных потоках. Становится еще хуже, если нескольким действиям требуется некоторое время, чтобы завершить выполнение, и мне нужно создать логику, чтобы вызывающая сторона ожидала результата.
Например, если executeTaskTwo()
требуется некоторое время для завершения, я выполню его в фоновом потоке, что означает, что executeTaskTwo()
вернется почти сразу, в то время как сама задача все еще будет выполняться. Но как я могу уведомить звонящего о его завершении, как только оно закончится?
Я полагаю, что решение включает в себя серьезную модификацию, возможно, некоторые библиотеки событий (я никогда раньше не работал с ними). Мне нужна отправная точка. Я предполагаю, что существуют какие-то шаблоны, но я не знаю, какие именно.
Обновление 1:
Еще немного информации об общей архитектуре и проблемах
Есть три объекта:
Hardware
- управляет аппаратными сигналами (входы, выходы). Заботится только об оборудовании, не задает вопросов о том, почему?
Network
- управляет удаленными подключениями к устройству. Заботится только о передаче данных. Опять же, ему не важно, что представляют собой данные.
Controller
- контролирует реальную задачу / алгоритм устройства (что делает это устройство). Это мозг устройства.
Каждая сущность работает в своем собственном потоке. Иногда происходит событие, и один объект должен отправить это событие другому объекту (или всем им). Например, команда с network
включает какой-либо светодиод, управляемый аппаратным обеспечением, или об ошибке включения этого индикатора следует сигнализировать как network
(уведомить удаленных клиентов), так и controller
(выполнить аварийную остановку).
Прямо сейчас у каждой сущности (класса) есть набор функций (методов), которые другие сущности вызывают, когда они этой сущностью что-то делают. Если вызываемой функции требуется время для выполнения, объект вызывающей стороны блокируется, что плохо. Создание фонового потока для обработки каждой команды (или события) также кажется неправильным.
Прямо сейчас каждый объект имеет свою очередь команд и выполняет свои команды последовательно (execute(queue.getNext())
), но это неэффективно, потому что некоторые команды выполняются быстро, а другие требуют времени и ресурсов.