Choosing a design pattern for a class that might change its internal attributes
I have a class that holds arbitrary state and it's defined like this:
class AbstractFoo
{
};
template <class StatePolicy>
class Foo : public StatePolicy, public AbstractFoo
{
};
The state policy contains only protected attributes that represent the state.
The state might be the same for multiple behaviors and they can be replaced at runtime. All Foo objects have the same interface to abstract the state itself and to enable storing Foo objects in containers. I would like to find the least verbose and the most maintainable way to express this.EDIT:
Here's some more info on my problem: Foo is a 开发者_StackOverflow社区class that represents a state and behavior of a certain hardware that can be changed either physically or through a UI (and there are multiple UIs). I have four more questions: 1) Would a signal/slot mechanism will do? 2) Is it possible to bind every emitted signal from a slot in Foo to have a pointer to Foo like it's a member class? 3) Should I use a visitor instead and treat Foo as a visited class? 4) Why is the StatePolicy a bad design?Here's the updated API:
class AbstractFoo
{
public:
virtual void /*or boost::signal*/ notify() = 0; // Updates the UI.
virtual void /*or boost::signal*/ updateState() = 0 // Updates the state
};
I don't understand your situation exactly, but here's my shot at it: what if you make an AbstractStatePolicy
instead? Example:
class AbstractStatePolicy
{
};
class Foo
{
AbstractStatePolicy *state_policy;
public:
Foo(AbstractStatePolicy *state_policy)
: state_policy(state_policy)
{
}
};
This way, instead of statically defining Foo
as a template using a StatePolicy
, you can dynamically set the StatePolicy
using an approach like this.
If you don't like the idea of having to specify the state_policy every time you create a Foo
, consider using a default value or writing a factory to instantiate Foo
s.
I don't think what you have is a very sensible approach. You should have a pure virtual base class that describes what your implementations can actually do, and then you can create concrete classes that inherit from the base class using whatever state you would need. You would then be able to interact with the state through whatever interface you defined for that base class. Now, if you have arbitrary, dynamic attributes that can change at runtime, then a good way to accomplish that is with a map or dictionary type; you can either map from strings (names of attributes) to strings (representing the attribute values), or if you want a little bit more type safety, you map from strings (names of attributes), to instances of boost::any.
精彩评论