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:
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.
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.