dependency injection - C++ injecting 'strategies' through constructor -


i'm developing complex calculations require 'steps' determined (strategy pattern type implementation) , i'm not sure best way inject step subcalculation classes main class.

i've looked policy-based design read policy design 'compile time polymorphism' not runtime. plus, wasn't sure how use templates of subcalculation classes need constructor parameters.

i've started implementing virtual 'interface' classes each step , injecting each step unique_ptr in constructor wasn't sure if correct 'modern c++' way.

i started implementing functionality in main class found made difficult if not impossible unit test each step independently.

the structure similar below:

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 input     // need calculation type   }    stepbresult performstepb(const stepbinput& requiredinput); };  class calculationstepctype1 { public:   calculationstepbtype2(const inputionlyneedfortype1& parameters)   {     // initialize class members input     // need calculation type   }    stepcresult performstepc(const stepcinput& requiredinput); };  class calculationstepctype2 { public:   calculationstepbtype2(const inputionlyneedfortype2& parameters)   {     // initialize class members input     // need calculation type   }    stepcresult performstepb(const stepcinput& requiredinput); };  class classthatusesallthecalculations { public:   classthatusesallthecalculations(/* take required parameters determine step types 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 use stepa , determine if should continue      auto stepbresult = stepbcalculator(somethingfromsteparesult);     // again, logic use stepb , determine if should continue      auto stepcresult = stepccalculator(somethingfromstepbresult);     // assemble final result      return thefinalresult   }     // other method needed setup calculation   private:   typeforstepacalculation stepacalculator;   typeforstepbcalculation stepbcalculator;   typeforstepccalculation stepccalculator; }; 

any on determining best design great appreciated.

whats simple inheritance?

struct stepa{     virtual steparesult perform(stepaparams)=0; };  struct somestepaimpl : public stepa{     virtual steparesult perform(stepaparams params) override {         //actual implementation     } }; 

whether calculation class uses reference (hast set on construction), std::reference_wrapper (not null, can changed later) or kind of (smart) pointer (might nullptr, don't forget check that, easiest when comes managing lifetime) depends on how plan use , how want manage lifetime of objects. example using unique_ptr did be:

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(...); } 

Comments

Popular posts from this blog

sql server - Cannot query correctly (MSSQL - PHP - JSON) -

php - trouble displaying mysqli database results in correct order -

C++ Linked List -