替代工厂(class 设计)
Alternative to a factory(class design)
我正在编写一个具有管道和舞台架构的合成器。我目前以这种方式创建我的舞台:
main.cpp
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 的 class 中使用工厂方法。很明显,每个专门阶段 class 都有可变参数,这对我来说行不通。我目前正在对所有构造函数参数进行硬编码:
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;
}
我有哪些选择?重要的是我 return 一个通用阶段* class 以避免为管道连接转换为特定的 classes。
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);
我在我的体系结构中真的很早,所以我想正确地确定这一点,一些文献和一般建议是我想要的。我不确定我想要什么。
另一种可能性是让 classes 在 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;
}
要让 class 注册自己,请定义一个创建自己的函数;
Stage* CreateLinearEnvelope()
{
return new LinearEnvelope(0.2f, 0.3f, 0.8f);
}
并在程序启动期间在注册表中注册;
RegisterStage(tageId::LINEAR_ENVELOPE, &CreateLinearEnvelope);
工厂函数也可能是一个 class 成员;
typedef Stage* (Stage::*CreateStage)();
RegisterStage
和 CreateStageFunctions
可能是静态的,如果初始化是单线程的或者你负责同步。
我正在编写一个具有管道和舞台架构的合成器。我目前以这种方式创建我的舞台:
main.cpp
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 的 class 中使用工厂方法。很明显,每个专门阶段 class 都有可变参数,这对我来说行不通。我目前正在对所有构造函数参数进行硬编码:
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;
}
我有哪些选择?重要的是我 return 一个通用阶段* class 以避免为管道连接转换为特定的 classes。
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);
我在我的体系结构中真的很早,所以我想正确地确定这一点,一些文献和一般建议是我想要的。我不确定我想要什么。
另一种可能性是让 classes 在 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;
}
要让 class 注册自己,请定义一个创建自己的函数;
Stage* CreateLinearEnvelope()
{
return new LinearEnvelope(0.2f, 0.3f, 0.8f);
}
并在程序启动期间在注册表中注册;
RegisterStage(tageId::LINEAR_ENVELOPE, &CreateLinearEnvelope);
工厂函数也可能是一个 class 成员;
typedef Stage* (Stage::*CreateStage)();
RegisterStage
和 CreateStageFunctions
可能是静态的,如果初始化是单线程的或者你负责同步。