【问题标题】:Alternative to a factory(class design)替代工厂(类设计)
【发布时间】:2015-02-07 22:23:14
【问题描述】:

我正在编写一个具有管道和舞台架构的合成器。我目前以这种方式创建我的阶段:

ma​​in.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 的类中使用工厂方法。很明显,每个专门的舞台类都有可变参数,这对我来说行不通。我目前正在对所有构造函数参数进行硬编码:

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

我有哪些选择?重要的是我返回一个 Generic Stage* 类以避免强制转换为特定的管道连接类。

ma​​in.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);

我的架构真的很早,所以我想正确地确定这一点,一些文献和一般建议是我想要的。我不确定我想要什么。

【问题讨论】:

    标签: c++ design-patterns


    【解决方案1】:

    另一种可能性是让类在 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 可能是静态的,如果初始化是单线程的,或者你负责同步。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多