基于策略的设计决策
我有一个名为 Device 的类,据我所知,它接受两个策略:StatePolicy 和 BehaviorPolicy。
StatePolicy 保存并管理设备的状态。
BehaviorPolicy 包装用 C 或 C++ 编写的设备驱动程序。
现在我有两个问题:
- 国家政策和行为政策如何协调?
- 如何将所有设备存放在一个容器内?由于设备
的类型不同于设备 的类型。我无法将它们存放在一个容器中。
编辑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:
- How to coordinate between the state and the behavior policies?
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是完整的设计,它可以工作并且做得很好:
@cjhuit:一般来说我认为你是对的,但看一下并告诉我你的想法。
Here is the full design that works and does it's job pretty well at it:
@cjhuitt: Generally I think you are right but take a look and tell me what do you think.
我不确定你在第一个问题中的意思。关于第二个,您可以为 Device 类模板创建一个 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.
至于第一个问题:
如果您需要协调这两项政策,它们并不是正交的。如果它们不是正交的,它们就不太适合您正在进行的设计类型。但是,查看示例代码,我发现您已经有了依赖于状态的行为,所以我不知道这个问题的意义是什么......
至于第二个问题, ltcmelo 具有正确的答案,该答案也嵌入在您的代码中。如果您正在寻找一种将模板化类保存在通用容器中的方法,那么这是最好的方法。为了克服
changeState
问题,您需要创建一些通用函数来更改您想要的状态...例如open
、close
等。如果您无法实现这些功能,则可能您的代码太通用。As for the first question:
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... likeopen
,close
, etc. If you can't make those functions, perhaps your code is too generic.