2016-11-11 71 views
0

我开发需要的“阶梯”的一些复杂的计算注入“策略”来确定(战略格局类型的实现),我不知道步骤subcalculation类注入到主的最佳方式类。C++通过构造

我已经研究过基于策略的设计,但读的政策设计是“编译时多态”不是运行。另外,我不确定如何使用模板,因为某些子计算类需要构造函数参数。

我已经开始实施虚拟“接口”类的每一个步骤和注射每一步在构造函数的unique_ptr但不知道这是否正确的“现代C++”的方式。

我最初开始实施主类中的所有功能,但发现这使得它很难甚至无法进行单元测试独立的每一步。

的结构类似于如下:

class CalculationStepA 
{ 
public: 
    // default constructor 

    StepAResult performStep(const input& requiredInput); 
}; 

class CalculationStepBType1 
{ 
public: 
    // default constructor 

    StepBResult performStepB(const stepBInput& requiredInput); 
}; 

class CalculationStepBType2 
{ 
public: 
    CalculationStepBType2(const inputIOnlyNeedForType2& parameters) 
    { 
    // initialize class members from input 
    // need for this calculation type 
    } 

    StepBResult performStepB(const stepBInput& requiredInput); 
}; 

class CalculationStepCType1 
{ 
public: 
    CalculationStepBType2(const inputIOnlyNeedForType1& parameters) 
    { 
    // initialize class members from input 
    // need for this calculation type 
    } 

    StepCResult performStepC(const stepCInput& requiredInput); 
}; 

class CalculationStepCType2 
{ 
public: 
    CalculationStepBType2(const inputIOnlyNeedForType2& parameters) 
    { 
    // initialize class members from input 
    // need for this calculation type 
    } 

    StepCResult performStepB(const stepCInput& requiredInput); 
}; 

class ClassThatUsesAllTheCalculations 
{ 
public: 
    ClassThatUsesAllTheCalculations(/* take required parameters that determine which step types I need */) 
    {} 

    // possible constructor? 
    ClassThatUsesAllTheCalculations(
     std::unique_ptr<IStepACalculationStrategy> stepA, 
     std::unique_ptr<IStepBCalculationStrategy> stepB,  
     std::unique_ptr<IStepCCalculationStrategy> stepC) 
    { 

    } 

    FinalResult executeCalculation(const finalInputRequiredHere& input) 
    { 
    auto stepAresult = stepACalculator(somethingFromInput); 
    // logic to use stepA and determine if we should continue 

    auto stepBresult = stepBCalculator(somethingFromStepAResult); 
    // again, logic to use stepB and determine if we should continue 

    auto stepCresult = stepCCalculator(somethingFromStepBResult); 
    // assemble final result 

    return theFinalResult 
    } 


    // other method needed to setup calculation 


private: 
    TypeForStepACalculation stepACalculator; 
    TypeForStepBCalculation stepBCalculator; 
    TypeForStepCCalculation stepCCalculator; 
}; 

上确定最佳设计将是巨大的赞赏任何帮助。

+0

我的想法是,试图创建用来构成动作硬编码号为一类顶级类是过于严格。我觉得试图做一些流畅的界面,其中的功能组成来执行他们的行动并返回结果,以便下一个可能使用它可能是一个更好的选择。我没有真正给它足够的想法来制定一个具体的例子,鉴于你的例子是如此抽象,这也很困难。您可以从c#Linq或java流中获取示例。 –

+0

@PaulRooney有趣的建议。我熟悉Linq,因为我主要在工作中使用C#。我会尽力把这些东西放在一起。 – RobertW

回答

0

简单遗传是什么?

struct StepA{ 
    virtual StepAResult perform(StepAParams)=0; 
}; 

struct someStepAImpl : public StepA{ 
    virtual StepAResult perform(StepAParams params) override { 
     //actual implementation 
    } 
}; 

无论你的计算类,然后使用一个引用(HAST对建筑进行设置),一个std::reference_wrapper(不为空,但以后可以改变)或某种(智能)指针(可能是nullptr,唐不要忘了检查一下,但是在管理生命周期时最简单)取决于你打算如何使用它以及如何管理对象的生命周期。使用unique_ptr一个例子像你一样会:

class Calculator 
{ 
public: 
    Calculator(
     std::unique_ptr<StepA> stepA, 
     std::unique_ptr<StepB> stepB,  
     std::unique_ptr<StepC> stepC 
    ) 
    :m_stepA(std::move(stepA)),m_stepB(std::move(stepB)),m_stepC(std::move(stepC)) 
    {} 

    FinalResult executeCalculation(const finalInputRequiredHere& input) 
    { 
     //logic 
     auto stepAresult = stepA->perform(StepAParams); 
     //logic 
     auto stepBresult = stepB->perform(StepBParams); 
     //logic 
     auto stepCresult = stepC->perform(StepAParams); 
     //logic 
     return FinalResult(); 
    } 

private: 
    std::unique_ptr<StepA> m_stepA=nullptr; 
    std::unique_ptr<StepB> m_stepB=nullptr; 
    std::unique_ptr<StepC> m_stepC=nullptr; 
}; 


void somewhereElse(){ 
    std::unique_ptr<StepA> stepa(new someStepAImpl()); 
    std::unique_ptr<StepB> stepa(new someStepBImpl()); 
    std::unique_ptr<StepC> stepa(new someStepCImpl()); 
    Calculator calc(
     std::move(stepa), 
     std::move(stepb), 
     std::move(stepc) 
    ); 
    calc.executeCalculation(...); 
} 
+0

这是完美的工作。这是我最初倾向于的解决方案。我创建了一个工厂来建立并注入所需的步骤计算。 – RobertW