3

私が見る限り、 StatePolicyBehaviorPolicyの 2 つのポリシーを受け入れるDeviceというクラスがあります。 StatePolicyは、デバイスの状態保持および管理します。BehaviorPolicy は、C または C++ で記述されたデバイス ドライバーをラップします。 今、私は2つの質問があります:


  1. 状態と行動ポリシーをどのように調整するか?
  2. すべてのデバイスを 1 つのコンテナー内に保管するにはどうすればよいですか? Device<X, Y> のタイプは Device<N, M> とは異なるため、1 つのコンテナーに格納することはできません。

編集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: これにより、コードは 1 つの欠点で機能します。許可されているすべての状態タイプのリストを維持する必要があります。私にはビジターのパターンに少し似ています。何かご意見は?

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;
}

@cjhuitt: 一般的にはあなたが正しいと思いますが、見てどう思うか教えてください。

于 2009-08-23T17:54:57.733 に答える
1

最初の質問について:

状態と行動ポリシーをどのように調整するか?

2 つのポリシーを調整する必要がある場合、それらは直交していません。それらが直交していない場合、それらはあなたが行っているデザインのタイプにも適していません. ただし、サンプルコードを見ると、すでに状態に依存した動作をしているため、この質問のポイントがわかりません...

2 番目の質問については、ltcmeloが正しい答えを持っており、これもコードに組み込まれています。テンプレート化されたクラスを汎用コンテナーに保持する方法を探している場合は、それが最善の方法です。この問題を解決するには、changeState状態を希望どおりに変更する汎用関数を作成する必要があります。openclose

于 2009-08-23T14:56:18.047 に答える
1

I'm not sure about what you mean in the first question. Regarding the second one, you can create a DeviceBase class for the Device class template. Then, you can store pointers to this base class in containers.


class DeviceBase
{
  //...
};

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