2017-01-19 2 views
1

Я не был уверен в лучшем имени для этой темы, но я пытаюсь реорганизовать некоторый код и удалить некоторую развязку. Я вынужден использовать Visual Studio 2005 C++ без boost, не спрашиваю ... (Так что не C++ 11 или новее)Как успешно отделить эти классы

У меня есть протокол, который получает сообщения, а протокол содержит синтаксический анализатор и процессор , Parser извлекает информацию из сообщения и заполняет структуру. Затем структура передается в процессор для принятия дальнейших мер.

class Protocol 
{ 
    Parser parser; 
    Processor processor; 

public: 
    Protocol() : parser(processor) 
    { 

    } 

    handleMessage(Message& message) 
    { 
     ParsedData parsedData; 
     parser.parse(message, parsedData); 
    } 
} 

class Parser 
{ 
    Processor processor; 

public: 
    Parser() 
    { 

    } 

    Parser(Processor& p) : processor(p) 
    { 
    } 

    parse(Message& message, ParsedData& parsedData) 
    { 
     if(message.type == "whatever") 
     { 
      parseLevel2(message.message, parsedData); 
     } 
     //else if Other message types 
    } 

    parseLevel2(MessageLevel2& message, ParsedData& parsedData) 
    { 
     //Keep going down the rabbit hole, but for simplicity it ends here 
     parsedData.blah = "some data"; 
     processor.ProcessBlahMessage(parsedData); 
    } 
} 

class Processor 
{ 
public: 
    Processor() 
    { 
    } 

    ProcessBlahMessage(ParsedData& parsedData) 
    { 
     //Do logic 
    } 
} 

Я надеялся лишить процессор с Parser поэтому он стал больше, как это ...

class Protocol 
{ 
    Parser parser; 
    Processor processor; 

public: 
    Protocol() : parser(processor) 
    { 

    } 

    handleMessage(Message& message) 
    { 
     ParsedData parsedData; 
     parser.parse(message, parsedData); //This will not call the processor from within it 
     processor.process(parsedData); //This is the new 

    } 
} 

Единственная проблема, которая мешает мне делать это у меня будет иметь связка операторов if в методе процесса.

process(ParsedData& parsedData) 
{ 
    if(parsedData.type == "blah") 
    { 
     ProcessBlahMessage() 
    } 
    else if(parsedData.type == "grah") 
    { 
     ProcessGrahMessage() 
    } 
    //etc... 
} 

Мой вопрос в том, как я могу избежать всех тех утверждений if, где я по существу просто разбираю его снова? Если я дам parsedData указатель на функцию или lambda, то мне все равно понадобится ссылка на процессор в синтаксическом анализаторе.

+0

Существует ли общий шаблон обработки сообщений? Если это так, то вы можете создать базовый класс 'MessageData', а затем для каждого типа сообщения создайте свой собственный производный класс для данных, например' BlahMessageData', 'GrahMessageData'. После этого ваш метод parse вернет 'MessageData', который работает как [FactoryMethod] (https://sourcemaking.com/design_patterns/factory_method). И тогда 'MessageData' будет обрабатываться обычным образом, без каких-либо утверждений :) – MrPisarik

+0

@Taztingo Возможно, я ошибаюсь, но независимо от того, будете ли вы * Strip *' Processor' из 'Parser', вы все еще придерживаетесь' if' условия. Что делает * Stripping * что-то делать? Кроме того, что вы на самом деле имеете в виду * Это не будет вызывать *? Вам все еще нужно разбирать данные, не так ли? – CKing

+0

@Cking Комментарий отрезался. Предполагалось, что это не вызовет процессор вручную. Я обновлю его, и, надеюсь, он не будет снова отключен. Цель вопроса состоит в том, как разбить его и как удалить инструкции if из процессора. – Taztingo

ответ

0

вы можете попробовать это: 1) в ваших проанализированных данных вместо .blah и .grah магазина vector<void*> 2) при условии создания нового объекта л (или любой другой тип сообщения) и поместить указатель на него в вектор (с использованием типа как индекс). 3) в вашем векторе хранения процессора обработчиков. перейдите в тип процессора вместе с анализируемыми данными, поэтому вы можете вызвать правильный обработчик для правильного указателя 4) в вашем листе обработчика void * to blah * (или какой-либо реальный тип)

+0

Это похоже на то, о чем я думал, кроме как с unordered_map. Хорошая идея. – Taztingo

Смежные вопросы