При разработке внутренней системы сообщений, такой как шаблон «Посредник» или «Наблюдатель», каков наилучший способ инкапсулировать объекты сообщений, которые передаются?
Рассмотрим следующий объект сообщения, который сообщает какой-либо службе запустить новый Job
, Сообщение содержит Job
это должно быть запущено.
#define MESSAGE_JOB = 1
class NewJobMessage: public Message
{
virtual int getType() { return MESSAGE_JOB; }
Job* m_Job;
}
Теперь сообщение может быть обработано в следующем handleMessage
Функция службы:
bool JobService::handleMessage( Message* msg )
{
switch( msg.getType() )
{
case MESSAGE_JOB:
runJob( (dynamic_cast<NewJobMessage*>( msg ))->m_Job );
return true;
case default:
return false;
}
}
Кажется, все в порядке, но NewJobMessage должен знать о классе Job, даже если он никогда не использует его осмысленно; это просто транспортировка.
Предпочитается ли какой-либо другой способ избежать связывания сообщения с данными? Я думал об использовании void*
и кастинг, но это кажется хакерским и может сбить с толку, если кто-то другой будет анализировать мой код.
Это учебник void *
быть подходящим Реальная сторона void *
проверка типа во время выполнения, но ваш getType()
Метод — это большая подсказка, что вы уже спустились в кроличью нору.
Чтобы сделать его непонятным, просто сохраняйте структуру простой.
// No need to inherit from this.
struct Message {
int type;
void * data;
};
Пока вы кодируете организованным способом, это не должно сбивать с толку, нетипизированные данные являются стандартный подход для очередей сообщений.
Вы не упомянули, как эти сообщения передаются или как далеко они могут пройти (по сети?), Но в целом я бы настоятельно рекомендовал НЕ передавать нативные объекты. Это рецепт боли и страданий в будущем. Это кошмар обслуживания и отладки, вектор атаки на систему безопасности, проблема связывания проекта, и она только усугубляется, когда эта система расширяется позже (потому что это всегда происходит).
Таким образом, есть несколько способов решить эту проблему:
При прочих равных условиях я бы склонялся к JSON, если скорость, с которой вам нужно обрабатывать и передавать эти запросы, не будет настолько высокой, что ваша обработка не сможет справиться. Это должно быть довольно легко с помощью современных библиотек C ++ для обработки JSON.