2015-02-07 2 views
0

파이프 및 무대 아키텍처가있는 신시사이저를 쓰고 있습니다. 나는 현재 이런 식으로 내 단계를 만듭니다공장에 대한 대안 (수업 설계)

MAIN.CPP 내가 StageRegistry라는 클래스의 팩토리 메소드를 사용하고

Stage *s1 = pipeLine.AddStage(StageRegistry::StageId::SIN_OSCILLATOR); 
Stage *s2 = pipeLine.AddStage(StageRegistry::StageId::WAVE16BIT_WRITER); 
Stage *s3 = pipeLine.AddStage(StageRegistry::StageId::LINEAR_ENVELOPE); 
Stage *s4 = pipeLine.AddStage(StageRegistry::StageId::MULTIPLIER); 

. 모든 특수화 된 무대 수업에 가변 매개 변수가 있고 이것이 나에게 도움이되지 않는다는 것이 분명 해졌습니다.

StageRegistry.cpp

Stage* StageRegistry::CreateStage(const StageId stageId) 
{ 
    Stage *s = nullptr; 

    switch (stageId) 
    { 
     case StageId::SIN_OSCILLATOR: 
     { 
      return new SinOscillator(48); 
     } 
     break; 

     case StageId::WAVE16BIT_WRITER: 
     { 
      return new WaveFileWriter("out1.wav", 1); 
     } 
     break; 

     case StageId::LINEAR_ENVELOPE: 
     { 
      return new LinearEnvelope(0.2f, 0.3f, 0.8f); 
     } 

     case StageId::MULTIPLIER: 
     { 
      return new Multiplier(); 
     } 
     break; 
    } 

    return s; 
} 

내 대안은 무엇인가 : 나는 현재 모든 생성자 PARAMS를 하드 코딩하는거야? 파이프 연결을 위해 특정 클래스로 캐스트되지 않도록 Generic Stage * 클래스를 반환하는 것이 중요합니다.

MAIN.CPP는

SharedBuffer *sb0 = pipeLine.CreatePipe(); 
SharedBuffer *sb1 = pipeLine.CreatePipe(); 
SharedBuffer *sb2 = pipeLine.CreatePipe(); 
s1->SetOutputPipe(0, sb0); 
s3->SetOutputPipe(0, sb1); 
s4->SetInputPipe(0, sb0); 
s4->SetInputPipe(1, sb1); 
s4->SetOutputPipe(0, sb2); 
s2->SetInputPipe(0, sb2); 

내가 제대로이를 못 싶습니다 그래서 난 정말 일찍 내 건축 해요, 일부 문학과 일반적인 조언은 내가하고 싶은 것입니다. 나는 내가 원하는 것을 확신하지 못한다.

답변

0

또 다른 가능성은 클래스가 StageRegistry에 등록되도록하는 것입니다. StageRegistry는 다음과 같습니다.

typedef Stage* (*CreateStage)(); 
typedef map<StageId, CreateStage> CreateStageMap; 
CreateStageMap CreateStageFunctions; 

StageRegistry::RegisterStage(const StageId stageId, CreateStage CreateStageFunction) 
{ 
    CreateStageFunctions[stageId]=CreateStageFunction; 
} 

Stage* StageRegistry::CreateStage(const StageId stageId) 
{ 
    if (CreateStageFunctions.find(stageId) == CreateStageFunctions.end()) 
     return nullptr; 

    CreateStage CreateStageFunc =CreateStageFunctions[stageId]; 
    Stage *s = *CreateStageFunc(); 
    return s; 
} 

클래스 자체를 등록하려면 자체를 만드는 함수를 정의하십시오.

Stage* CreateLinearEnvelope() 
{ 
    return new LinearEnvelope(0.2f, 0.3f, 0.8f); 
} 

그리고 프로그램 시작 중에 레지스트리에 등록하십시오.

RegisterStage(tageId::LINEAR_ENVELOPE, &CreateLinearEnvelope); 

팩토리 함수는 클래스 멤버 일 수도 있습니다. 초기화가 단일 스레드 또는 당신이 동기화를 돌봐 경우

typedef Stage* (Stage::*CreateStage)(); 

RegisterStageCreateStageFunctions 아마 정적이 될 수 있습니다.