Я не был уверен в лучшем имени для этой темы, но я пытаюсь реорганизовать некоторый код и удалить некоторую развязку. Я вынужден использовать 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, то мне все равно понадобится ссылка на процессор в синтаксическом анализаторе.
Существует ли общий шаблон обработки сообщений? Если это так, то вы можете создать базовый класс 'MessageData', а затем для каждого типа сообщения создайте свой собственный производный класс для данных, например' BlahMessageData', 'GrahMessageData'. После этого ваш метод parse вернет 'MessageData', который работает как [FactoryMethod] (https://sourcemaking.com/design_patterns/factory_method). И тогда 'MessageData' будет обрабатываться обычным образом, без каких-либо утверждений :) – MrPisarik
@Taztingo Возможно, я ошибаюсь, но независимо от того, будете ли вы * Strip *' Processor' из 'Parser', вы все еще придерживаетесь' if' условия. Что делает * Stripping * что-то делать? Кроме того, что вы на самом деле имеете в виду * Это не будет вызывать *? Вам все еще нужно разбирать данные, не так ли? – CKing
@Cking Комментарий отрезался. Предполагалось, что это не вызовет процессор вручную. Я обновлю его, и, надеюсь, он не будет снова отключен. Цель вопроса состоит в том, как разбить его и как удалить инструкции if из процессора. – Taztingo