Инкапсуляция и усиление Объекты сообщения

При разработке внутренней системы сообщений, такой как шаблон «Посредник» или «Наблюдатель», каков наилучший способ инкапсулировать объекты сообщений, которые передаются?

Рассмотрим следующий объект сообщения, который сообщает какой-либо службе запустить новый 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* и кастинг, но это кажется хакерским и может сбить с толку, если кто-то другой будет анализировать мой код.

0

Решение

Это учебник void * быть подходящим Реальная сторона void * проверка типа во время выполнения, но ваш getType() Метод — это большая подсказка, что вы уже спустились в кроличью нору.

Чтобы сделать его непонятным, просто сохраняйте структуру простой.

// No need to inherit from this.
struct Message {
int type;
void * data;
};

Пока вы кодируете организованным способом, это не должно сбивать с толку, нетипизированные данные являются стандартный подход для очередей сообщений.

0

Другие решения

Вы не упомянули, как эти сообщения передаются или как далеко они могут пройти (по сети?), Но в целом я бы настоятельно рекомендовал НЕ передавать нативные объекты. Это рецепт боли и страданий в будущем. Это кошмар обслуживания и отладки, вектор атаки на систему безопасности, проблема связывания проекта, и она только усугубляется, когда эта система расширяется позже (потому что это всегда происходит).

Таким образом, есть несколько способов решить эту проблему:

  • Кодировать информацию с помощью CDR или каким-либо другим способом кодировать информацию о работе. Получатель переворачивает CDR, чтобы получить информацию обратно, даже если это не тот же язык, система или размер / порядок байтов. Это немного утомительно для кода, но не дорого в вычислительном отношении или в пространстве.
  • Маршалл запрос на что-то более высокого уровня, например, JSON или XML, в зависимости от ваших предпочтений и опыта, а также типов информации в данных. Это обычно довольно легко с помощью сторонней библиотеки, но преобразование в / из текста и его передача немного дороже. Также намного легче диагностировать проблемы и исследовать вещи в пути.

При прочих равных условиях я бы склонялся к JSON, если скорость, с которой вам нужно обрабатывать и передавать эти запросы, не будет настолько высокой, что ваша обработка не сможет справиться. Это должно быть довольно легко с помощью современных библиотек C ++ для обработки JSON.

0

По вопросам рекламы [email protected]