基于策略的设计决策

发布于 2024-08-02 10:37:35 字数 1935 浏览 7 评论 0原文

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

  1. 国家政策和行为政策如何协调?
  2. 如何将所有设备存放在一个容器内?由于设备的类型不同于设备的类型。我无法将它们存放在一个容器中。

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

预先感谢,
奥马尔.

I have a class called Device that accepts two policies as far as I can see: StatePolicy and BehaviorPolicy.
The StatePolicy holds and manages the state of the device.
The BehaviorPolicy wraps the device driver that is written in C or C++.
Now I have two questions:

  1. How to coordinate between the state and the behavior policies?
  2. How do I store all the devices inside one container? Since Device<X, Y>'s type is different then Device<N, M> I cannot store them with one container.

EDIT 1:
Here's some code to illustrate my problem:

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

EDIT 2:
This makes the code works with one downside, I have to maintain a list of all allowed state types. It looks a bit like the visitor pattern to me.
Any thoughts?

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

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

Thanks in advance,
Omer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吃颗糖壮壮胆 2024-08-09 10:37:35

这是完整的设计,它可以工作并且做得很好:

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

Here is the full design that works and does it's job pretty well at it:

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: Generally I think you are right but take a look and tell me what do you think.

软糖 2024-08-09 10:37:35

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


class DeviceBase
{
  //...
};

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

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
{
  //...
};
沒落の蓅哖 2024-08-09 10:37:35

至于第一个问题:

国家和行为政策之间如何协调?

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

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

As for the first question:

How to coordinate between the state and the behavior policies?

If you need to coordinate between the two policies, they are not orthogonal. If they aren't orthogonal, they won't lend themselves as well to the type of design you are doing. However, looking at the example code, I see that you already have the behavior relying on the state, so I don't know what the point of this question is...

As for the second question, ltcmelo has the correct answer, which is also embedded in your code. If you are looking for a way to keep templated classes in a generic container, that is your best way. In order to overcome the changeState problem, you'll need to make some generic function(s) to change the states how you want... like open, close, etc. If you can't make those functions, perhaps your code is too generic.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文