3

我有一个名为Device的类,据我所知,它接受两个策略:StatePolicyBehaviorPolicy
StatePolicy保存和管理设备的状态。BehaviorPolicy
包装用 C 或 C++ 编写 的设备驱动程序。 现在我有两个问题:

  1. 国家政策与行为政策如何协调?
  2. 如何将所有设备存储在一个容器中?由于 Device<X, Y> 的类型与 Device<N, M> 不同,我无法将它们存储在一个容器中。

编辑1:这里有一些代码来说明我的问题:

class AbstractDevice
{
public:
  virtual ~AbstractDevice() {}

  virtual void performAction() = 0;
  virtual const string &getName() const = 0;
  //virtual void changeState(const ??? &_state) = 0;  If I put a template here it won't solve my problem
};

template<typename T>
class State
{
private:
  T state;
protected:
  typedef T StateType;
public:
  State() : state(1) {}

  const T &getState() { return state; }
  void setState(const T _state) { state = _state; }
};

template <class StatePolicy>
class LightbulbBehvior : protected StatePolicy
{
private:
  typedef StatePolicy SP;
public:
  virtual void performAction()
  {
    if ( SP::getState() )
      cout << "do stuff";
  }

  void changeState(const typename SP::StateType &_state)
  {
    setState(_state);
    performAction();
  }
};

template<class StatePolicy, template <class> class BehviorPolicy>
class Device : public AbstractDevice, public BehviorPolicy<StatePolicy>
{
private:
  string sName;
public:
  const string &getName() const { return sName; }
};

int main()
{
  AbstractDevice *d = new Device<State<int>, LightbulbBehvior>();
  d->changeState(5);
  return 0;
}

编辑 2:这使得代码有一个缺点,我必须维护所有允许的状态类型的列表。在我看来,它有点像访客模式。有什么想法吗?

class AbstractDevice
{
public:
  virtual ~AbstractDevice() {}

  virtual void performAction() = 0;
  virtual const string &getName() const = 0;
  virtual void changeState(const int &_state) = 0;
};

在此先感谢,
奥马尔。

4

3 回答 3

2

这是完整的设计,并且做得很好:

class AbstractState
{
public:
  virtual ~AbstractState() {}
};

class AbstractDevice
{
public:
  virtual ~AbstractDevice() {}

  virtual void performAction() = 0;
  virtual const string &getName() const = 0;
  virtual void changeState(const AbstractState &_state) = 0;
};

template<typename T>
class State : public AbstractState
{
private:
  T state;
protected:
  typedef T StateType;
public:
  State() {}
  State(const T _state) : state(_state) {}

  const T &getState() const { return state; }
  void setState(const T _state) { state = _state; }
};

template <class StatePolicy>
class LightbulbBehvior : protected StatePolicy
{
private:
  typedef StatePolicy SP;
public:
  virtual void performAction()
  {
    if ( SP::getState() )
      cout << "do stuff";
  }

  void changeState(const typename SP::StateType &_state)
  {
    setState(_state);
    performAction();
  }
};

template<class StatePolicy, template <class> class BehviorPolicy>
class Device : public AbstractDevice, public BehviorPolicy<StatePolicy>
{
private:
  string sName;

  typedef BehviorPolicy<StatePolicy> BP;
  typedef StatePolicy SP;
public:
  const string &getName() const { return sName; }

  void performAction()
  {
    BP::performAction();
  }

  void changeState(const AbstractState &_state)
  {
    BP::changeState(((const SP &)_state).getState());
  }
};

int main()
{
  AbstractDevice *d = new Device<State<int>, LightbulbBehvior>();
  d->changeState(State<int>(5));
  delete d;
  return 0;
}

@cjhuit:总的来说,我认为您是对的,但请看一下并告诉我您的想法。

于 2009-08-23T17:54:57.733 回答
1

我不确定你在第一个问题中的意思。关于第二个,您可以为Device类模板创建一个DeviceBase类。然后,您可以将指向此基类的指针存储在容器中。


class DeviceBase
{
  //...
};

template <class T1, class T2>
class Device : public DeviceBase
{
  //...
};
于 2009-08-23T14:06:20.920 回答
1

至于第一个问题:

国家政策与行为政策如何协调?

如果您需要在两个策略之间进行协调,它们不是正交的。如果它们不是正交的,它们就不会适合你正在做的设计类型。但是,查看示例代码,我看到您已经有了依赖状态的行为,所以我不知道这个问题的重点是什么......

至于第二个问题,ltcmelo有正确答案,也嵌入在你的代码中。如果您正在寻找一种将模板类保存在通用容器中的方法,那是您最好的方法。为了克服这个changeState问题,你需要创建一些通用函数来改变你想要的状态......比如openclose等等。如果你不能制作这些函数,也许你的代码通用了。

于 2009-08-23T14:56:18.047 回答