2017-01-19 1 views
1

이 스레드의 가장 좋은 이름은 확실하지 않지만 일부 코드를 리팩토링하고 일부 디커플링을 제거하려고합니다. 나는 Visual Studio 2005 C++을 부스트없이 사용하도록 강요 받고있다. (C++ 11 이상이 아님)성공적으로이 클래스들을 디커플링하는 방법

메시지를받는 프로토콜이 있고 프로토콜에 파서와 프로세서가 포함되어있다. . 파서는 메시지에서 정보를 추출하고 구조를 채 웁니다. 그런 다음 구조가 처리기로 전달되어 이에 대한 추가 조치가 취해집니다. 더 같이되었다 있도록

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 
    } 
} 

나는 내가이해야 할 것입니다

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에 함수 포인터 나 람다를 주면 파서의 프로세서에 대한 참조가 필요합니다.

+0

일반적인 메시지 처리 패턴이 있습니까? 그렇다면 기본 클래스'MessageData'를 생성 한 다음, 각 메시지 유형에 대해 데이터의 파생 클래스 (예 :'BlahMessageData','GrahMessageData')를 생성 할 수 있습니다. 그런 다음 구문 분석 메서드는 [FactoryMethod] (https://sourcemaking.com/design_patterns/factory_method)처럼 작동하는'MessageData'를 반환합니다. 그리고 나서'MessageData'는 if 문없이 일반적인 방법으로 처리 될 것입니다 :) – MrPisarik

+0

@Taztingo 틀렸을 수도 있습니다 만,'Parser'에서'Processor'를 제거했는지에 상관없이'if' 정황. * 스트립 핑은 무엇과 관련이 있습니까? 또한, 당신은 정말로 * * 이것을 부르지 않을 것입니다. 아직도 데이터를 파싱해야합니까? – CKing

+0

@Cking 댓글이 잘 렸습니다. 이것은 프로세서를 수동으로 호출하지 않는다고 말한 것입니다. 나는 그것을 갱신 할 것이고 희망적으로 그것은 다시 끊어지지 않을 것이다. 문제의 목적은 프로세서를 제거하는 방법과 프로세서에서 if 문을 제거하는 방법입니다. – Taztingo

답변

0

이 시도 할 수 있습니다 : 1) 대신 .blah 및 .grah 저장소의 당신의 분석 데이터에 어떤 메시지 유형의 새 ㅋ 객체 (또는 생성) 및 유형을 사용하여 (벡터로 포인터를 넣어 가정 vector<void*> 2) 색인으로). 3) 처리기의 프로세서 저장소 벡터에 있습니다. 올바른 포인터에 대해 올바른 핸들러를 호출 할 수 있도록 올바른 포인터를 호출 할 수 있도록 핸들러를 호출 할 수 있도록 핸들러를 호출 할 수 있도록 핸들러를 호출 할 수 있습니다. void *를 blah * (또는 실제 유형이 무엇이든)로 변환합니다.

+0

이것은 unordered_map을 제외하고 내가 생각했던 것과 비슷하다. 좋은 생각. – Taztingo

관련 문제