【问题标题】:Policy based design decisions基于策略的设计决策
【发布时间】:2009-08-23 13:11:38
【问题描述】:

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

  1. 如何协调状态和行为政策?
  2. 如何将所有设备存储在一个容器中?由于 Device 的类型与 Device 不同,因此我无法将它们存储在一个容器中。

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

提前致谢,
奥马尔。

【问题讨论】:

  • 我不认为这是基于策略的设计。我认为这只是一个具有多种授权或策略组合的设计决策。但设计是如何表示策略。它不是基于某些政策的设计。
  • 我认为这是一个很好的例子,说明人们很容易误解策略和一般模式的概念。
  • 我添加了一些代码来阐明我的意思。

标签: c++ templates policy-based-design


【解决方案1】:

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

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:一般来说我认为你是对的,但请看看并告诉我你的想法。

【讨论】:

    【解决方案2】:

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

    
    class DeviceBase
    {
      //...
    };
    
    template <class T1, class T2>
    class Device : public DeviceBase
    {
      //...
    };
    

    【讨论】:

      【解决方案3】:

      关于第一个问题:

      如何协调状态和行为政策?

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

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

      【讨论】:

        猜你喜欢
        • 2011-04-08
        • 2016-02-20
        • 1970-01-01
        • 2014-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        相关资源
        最近更新 更多