使用策略模式来改变方法及其关联状态

时间:2014-03-26 11:56:24

标签: c++ strategy-pattern

我喜欢创建一个课程" track"包含一个state成员和一个kalman-filter方法。我喜欢使用不同类型的卡尔曼滤波器。由于每个卡尔曼滤波器的接口是相同的,我想,我使用策略模式。 我有的问题,我也喜欢在改变策略时动态更改状态成员。因为使用的状态必须适合适当的卡尔曼滤波器。

这是一个简化的代码段:

class CVState : public StateBase { ... };
class CAState : public StateBase { ... };

卡尔曼基地:

class KalmanStrategy {
public:
  virtual void Prediction(StateBase* state) = 0;
  virtual void Correction(StateBase* state) = 0;
  virtual ~KalmanStrategy(){}

protected:
  KalmanStrategy() {}
};

卡尔曼子类:

class KalmanCV : public KalmanStrategy {
public:
  KalmanCV(){}
  void Prediction(StateBase* state) {...}
  void Correction(StateBase* state) {...}
};
class KalmanCA : public KalmanStrategy {...}

这是我的Track Class,它包含一个州成员,必须适合Kalman。

class track {
public:
  track() {
    Kalman_ = new KalmanCV;
  }
  void ChangeStateModel(KalmanStrategy* K) {
     Kalman_ = K;
     //state_ = new CVState; // the state in track has to fit to the Kalman Class
                             // in this Case KalmanCV
  }
private:
  KalmanStrategy* Kalman_;
  StateBase* state_;
}

有没有办法,在改变战略时,也改变状态_?

1 个答案:

答案 0 :(得分:2)

你可以这样做:

struct KalmanModelCV {
  typedef KalmanCV filter_t;
  typedef StateCV state_t;
};

class track {
public:
  track() {
    filter_ = NULL;
    state_ = NULL;
  }
  typedef<typename Model>
  void ChangeModel() {
     delete filter_;
     delete state_;
     filter_ = new typename Model::filter_t();
     state_ = new typename Model::state_t();
  }
private:
  KalmanStrategy* filter_;
  StateBase* state_;
};

track t;
t.ChangeModel<KalmanModelCV>();

但是,如果每个过滤器都需要自己的特定状态类型,那么最好将状态创建移动到过滤器类。例如:

class KalmanStrategy {
public:
  virtual void Prediction(StateBase* state) = 0;
  virtual void Correction(StateBase* state) = 0;
  virtual StateBase* CreateState() = 0;
  virtual ~KalmanStrategy(){}

protected:
  KalmanStrategy() {}
};

class KalmanCV : public KalmanStrategy {
public:
  KalmanCV(){}
  void Prediction(StateBase* state) {...}
  void Correction(StateBase* state) {...}
  StateBase* CreateState() { return new StateCV(); } // KalmanCV only works with StateCV!
};

class track {
public:
  track() {
    filter_ = NULL;
    state_ = NULL;
  }
  void ChangeModel(KalmanStrategy* strat) {
     delete filter_;
     delete state_;
     filter_ = strat;
     state_ = strat->CreateState();
  }
private:
  KalmanStrategy* filter_;
  StateBase* state_;
};