替代工厂(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)();

RegisterStageCreateStageFunctions 可能是静态的,如果初始化是单线程的或者你负责同步。