我有一个名为设备的课程,我可以看到两个政策: 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;
};
提前致谢,
奥马尔。
答案 0 :(得分: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:一般来说我认为你是对的但是看一看并告诉我你的想法。
答案 1 :(得分:1)
我不确定你在第一个问题中的意思。关于第二个,您可以为 Device 类模板创建 DeviceBase 类。然后,您可以在容器中存储指向此基类的指针。
class DeviceBase
{
//...
};
template <class T1, class T2>
class Device : public DeviceBase
{
//...
};
答案 2 :(得分:1)
至于第一个问题:
如何在州和行为政策之间进行协调?
如果您需要在两个策略之间进行协调,则它们不是正交的。如果它们不是正交的,它们也不会适合您正在进行的设计类型。但是,看一下示例代码,我发现你已经有了依赖于状态的行为,所以我不知道这个问题的重点是什么......
至于第二个问题,ltcmelo有正确的答案,它也嵌入在您的代码中。如果您正在寻找一种方法来将模板化类保存在通用容器中,那么这是您最好的方法。为了克服changeState
问题,您需要制作一些通用函数来更改状态,如open
,close
等。你不能做这些功能,也许你的代码太通用。