2012年7月26日 星期四

Policy based policy engine with c++ template

These codes are made by policy based programming. You can find the Policy –> RuleSet –> Rule to do some kinds of works. So, I named it as PolicyEngine. Add the comparators, rules, and collected these rules into rulesets. Finally, run it in an engine with many policies. If there is any problem, please contact me. I will answer it for you. Thank you.

   1: #ifndef __POLICY_BASED_ENGINE_H__
   2: #define __POLICY_BASED_ENGINE_H__
   3:  
   4: #include <vector>
   5: #include <string>
   6:  
   7: namespace POLICY_ENGINE_NAME_SPACE {
   8:  
   9:     typedef long POLICY_ENGINE_STATUS;  // for the return code
  10:  
  11:     typedef enum {
  12:         PE_ERR_POLICY_HIT = 1,
  13:         PE_ERR_RULESET_HIT,
  14:         PE_ERR_RULESET_NOT_HIT,
  15:         PE_ERR_RULE_HIT,
  16:         PE_ERR_RULE_NOT_HIT,
  17:     } POLICY_ENGINE_ERR_CODE;
  18:  
  19:     typedef enum {
  20:         POLICY_ENGINE_STATUS_FAILED = -1,
  21:         POLICY_ENGINE_STATUS_SUCCESSFULLY = 1,
  22:     } POLICY_ENGINE_STATUS_CODE;
  23:     
  24:     // default check data type
  25:     typedef struct CheckData_Tag {
  26:  
  27:     } CHECK_DATA, *PCHECK_DATA;
  28:  
  29:     template<class InputType>
  30:     struct RuleBase {
  31:         virtual POLICY_ENGINE_STATUS IsRuleHit(const InputType* pInput) = 0;
  32:     };
  33:  
  34:     template<
  35:         class CheckDataType = CHECK_DATA,
  36:         class InputType = CHECK_DATA
  37:     >
  38:     struct ComparatorAnd {
  39:         POLICY_ENGINE_STATUS Compare(const std::vector<RuleBase<InputType>*>& vecRules, const InputType* pInput) {
  40:             for(size_t i = 0; vecRules.size(); ++i) {
  41:                 // if there is one rule not satisfied, return not hit
  42:                 POLICY_ENGINE_STATUS status = vecRules.at(i)->IsRuleHit(pInput);
  43:                 if(status == PE_ERR_RULE_NOT_HIT)
  44:                     return PE_ERR_RULESET_NOT_HIT;
  45:             }
  46:             // all satisfied, return hit
  47:             return PE_ERR_RULESET_HIT;
  48:         };
  49:     };
  50:  
  51:     template<
  52:         class CheckDataType = CHECK_DATA,
  53:         class InputType = CHECK_DATA
  54:     >
  55:     struct ComparatorOr {
  56:         POLICY_ENGINE_STATUS Compare(const std::vector<RuleBase<InputType>*>& vecRules, const InputType* pInput) {
  57:             for(size_t i = 0; vecRules.size(); ++i) {
  58:                 // if there is one rule satisfied, return hit
  59:                 POLICY_ENGINE_STATUS status = vecRules.at(i)->IsRuleHit(pInput);
  60:                 if(status == PE_ERR_RULE_HIT)
  61:                     return PE_ERR_RULESET_HIT;
  62:             }
  63:             // All rules are not satisfied, return not hit
  64:             return PE_ERR_RULESET_NOT_HIT;
  65:         };
  66:     };
  67:  
  68:     template<
  69:         class CheckDataType = CHECK_DATA,
  70:         class InputType = CHECK_DATA
  71:     >
  72:     struct ComparatorCombinationOr {
  73:         POLICY_ENGINE_STATUS Compare(const std::vector<RuleBase<InputType>*>& vecRules, const InputType* pInput) {
  74:             unsigned int nRuleHitCount = 0;
  75:             for(size_t i = 0; vecRules.size(); ++i) {
  76:                 // if the hit rules number is match the number, return hit
  77:                 POLICY_ENGINE_STATUS status = vecRules.at(i)->IsRuleHit(pInput);
  78:                 if(status == PE_ERR_RULE_HIT)
  79:                     nRuleHitCount++;
  80:                 if(nRuleHitCount == m_nCombinationCount)
  81:                     return PE_ERR_RULESET_HIT;
  82:             }
  83:             return PE_ERR_RULESET_NOT_HIT;
  84:             // return not hit
  85:         };
  86:         unsigned long GetCombinationCount() {
  87:             return m_nCombinationCount;
  88:         };
  89:         void SetCombinationCount(unsigned long nCount) {
  90:             m_nCombinationCount = nCount;
  91:         };
  92:         unsigned long m_nCombinationCount;
  93:     };
  94:  
  95:     template<
  96:         class CheckDataType = CHECK_DATA, 
  97:         class InputType = CHECK_DATA,
  98:         template<class, class> class ComparatorType = ComparatorAnd
  99:     >
 100:     struct RuleSetBase : public ComparatorType<CheckDataType, InputType> {
 101:         virtual POLICY_ENGINE_STATUS IsRuleHit(const InputType* pInput) {
 102:             Compare(m_vecRules, pInput);
 103:         };
 104:         std::vector<RuleBase<InputType>*> m_vecRules;
 105:     };
 106:  
 107:     template<
 108:         template<class, class, template<class, class> class> class RuleSetBaseType = RuleSetBase
 109:     >
 110:     struct PolicyBase {
 111:         virtual POLICY_ENGINE_STATUS IsPolicyHit() {};
 112:         std::vector<RuleSetBaseType*> m_vecRuleSets;
 113:     };
 114:  
 115:     template<
 116:         class PolicyType,
 117:         class CheckDataType
 118:     >
 119:     struct EngineRunPolicy {
 120:         POLICY_ENGINE_STATUS_CODE RunEngine(const CheckDataType& checkData) {
 121:             for(size_t i = 0; i < m_vecPolicyPool.size(); ++i) {
 122:                 PolicyType* policy = m_vecPolicyPool.at(i);
 123:                 POLICY_ENGINE_STATUS_CODE retCode = policy->IsPolicyHit(checkData);
 124:             }
 125:             return PE_ERR_POLICY_HIT;
 126:         };
 127:     };
 128:  
 129:     template<
 130:         class EngineRunPolicyType,
 131:         class PolicyType,
 132:         class CheckDataType
 133:     >
 134:     struct EngineClass : public EngineRunPolicyType {
 135:     public:
 136:         EngineClass();
 137:         ~EngineClass();
 138:  
 139:  
 140:     private:
 141:         std::vector<PolicyType*> m_vecPolicyPool;
 142:     };
 143: };
 144:  
 145: #endif

沒有留言: