2016-11-11 73 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