Skip to main content
added 135 characters in body
Source Link
Doc Brown
  • 220.7k
  • 35
  • 411
  • 625

The extra parameter will only make sense in a layer of the code section where it clear that it is a specific parameter for athe class StateB object"lives". Let me call this "application layer".

Your state pattern implementation, especially the classes Context and State, however, livelives inside some "framework layer", which does not know anything about the specific StateB and it's requirements for an extra parameter.

The straightforward solution here is to make the parameter a a member of the class StateB, which has to be initialized before Context::transition() (which is part of the framework layer) is called. The initialization has to happen somewhere inside the application layer. You have basically the following options for this:

  • Pass the initial parameter value in the StateB constructor - that requires each constructor call to look like new StateB(context,initialA). That's feasible when initialA is available at all places and at the time where new StateB is called. In your example, this happens inside the class StateA, and it is not clear if initialA is accessable in that class, or a the point in time when StateB is constructed.

  • Provide an extra setter method StateB::setA(int initialA) and call it somewhere in the application layer where initialA is known, but, before Context::transition happens. That may require detection of when Context::current is of type StateB and a downcast. It also has some risk to be forgotten to be called and it gives StateB some mutable state.

In caseIf none of these options works for you don't want to introduce this extra member variable, you can also try thisto extend the framework in general:

  • Create an abstraction for "potentially extra parameters" in the framework layer, for example, an ExtraParameters class, and extend the signature of State::transition and Context::transition by this ExtraParameters. All states which don't need this parameter for a transition should ignore it, but StateB::transition can extract the parameter a from it.

    This will have the biggest impact on your current framework implementation, but it could be sensible when different State subclasses require different forms of extra parameters. There are some different possible design alternatives for ExtraParameters possible, you have to think which abstraction may makeone makes most sense for your case.

What to choose depends on your real-world context, how many State types require what kind of parameters, and where and when the parameters are become available in the system, and where or how often they change - that is something only you know, since you left no clue for us about itthese details in thisthe question.

The extra parameter will only make sense in a code section where it clear that it is a specific parameter for a StateB object. Let me call this "application layer".

Your state pattern implementation, especially the classes Context and State, however, live inside some "framework layer", which does not know anything about the specific StateB and it's requirements for an extra parameter.

The straightforward solution here is to make the parameter a a member of the class StateB, which has to be initialized before Context::transition() (which is part of the framework layer) is called. The initialization has to happen somewhere inside the application layer. You have basically the following options for this:

  • Pass the initial parameter value in the StateB constructor - that requires each constructor call to look like new StateB(context,initialA). That's feasible when initialA is available at all places and at the time where new StateB is called.

  • Provide an extra setter method StateB::setA(int initialA) and call it somewhere in the application layer, before Context::transition happens. That may require detection of when Context::current is of type StateB and a downcast. It also has some risk to be forgotten to be called and it gives StateB some mutable state.

In case you don't want to introduce this extra member variable, you can also try this:

  • Create an abstraction for "potentially extra parameters" in the framework layer, for example, an ExtraParameters class, and extend the signature of State::transition and Context::transition by this ExtraParameters. All states which don't need this parameter for a transition should ignore it, but StateB::transition can extract the parameter a from it.

    This will have the biggest impact on your current framework implementation, but it could be sensible when different State subclasses require different forms of extra parameters. There are some different design alternatives for ExtraParameters possible, you have to think which abstraction may make most sense for your case.

What to choose depends on your real-world context, how many State types require what kind of parameters, and where and when the parameters are become available in the system, and where or how often they change - that is something only you know, since you left no clue about it in this question.

The extra parameter will only make sense in a layer of the code where the class StateB "lives". Let me call this "application layer".

Your state pattern implementation, especially the classes Context and State, however, lives inside some "framework layer", which does not know anything about the specific StateB and it's requirements for an extra parameter.

The straightforward solution here is to make the parameter a a member of the class StateB, which has to be initialized before Context::transition() is called. The initialization has to happen somewhere inside the application layer. You have basically the following options for this:

  • Pass the initial parameter value in the StateB constructor - that requires each constructor call to look like new StateB(context,initialA). That's feasible when initialA is available at all places and at the time where new StateB is called. In your example, this happens inside the class StateA, and it is not clear if initialA is accessable in that class, or a the point in time when StateB is constructed.

  • Provide an extra setter method StateB::setA(int initialA) and call it somewhere in the application layer where initialA is known, but, before Context::transition. That may require detection of when Context::current is of type StateB and a downcast. It also has some risk to be forgotten to be called and it gives StateB some mutable state.

If none of these options works for you, you can also try to extend the framework in general:

  • Create an abstraction for "potentially extra parameters" in the framework layer, for example, an ExtraParameters class, and extend the signature of State::transition and Context::transition by this ExtraParameters. All states which don't need this parameter for a transition should ignore it, but StateB::transition can extract the parameter a from it.

    This will have the biggest impact on your current framework implementation, but it could be sensible when different State subclasses require different forms of extra parameters. There are some different possible design alternatives for ExtraParameters, you have to think which one makes most sense for your case.

What to choose depends on your real-world context, how many State types require what kind of parameters, and where and when the parameters are become available in the system, and where or how often they change - that is something only you know, since you left no clue for us about these details in the question.

added 361 characters in body
Source Link
Doc Brown
  • 220.7k
  • 35
  • 411
  • 625

The extra parameter will only make sense in a code section where it clear that it is a specific parameter for a StateB object. Let me call this "application layer".

Your state pattern implementation, especially the classes Context and State, however, live inside some "framework layer", which does not know anything about the specific StateB and it's requirements for an extra parameter.

The straightforward solution here is to make the parameter a a member of the class StateB, which has to be initialized before Context::transition() (insidewhich is part of the framework layer) is called. The initialization has to happen somewhere inside the application layer. You have basically the following options for this:

  • passPass the initial parameter value in the StateB constructor - that requires each constructor call to look like new StateB(context,initialA). That's feasible when initialA is available at all places and at the time where new StateB is called.

  • provideProvide an extra setter method StateB::setA(int initialA) and call it somewhere in the application layer, where it is appropriatebefore Context::transition happens. That may require detection of when Context::current is of type StateB and a downcast. It also has some risk to be forgotten to be called and it gives StateB some mutable state.

In case you don't want to introduce this extra member variable, you can also try this:

  • create a generalization of "potentially extra parameters" in the framework layer, for example, an ExtraParameters class, and extend the signature of State::transition and Context::transition by this ExtraParameters. All states which don't need this parameter should ignore it, but StateB::transition can extract the parameter a from it. This will have the biggest impact on your current framework implementation, but it could be sensible when different State subclasses require different forms of extra parameters.

    Create an abstraction for "potentially extra parameters" in the framework layer, for example, an ExtraParameters class, and extend the signature of State::transition and Context::transition by this ExtraParameters. All states which don't need this parameter for a transition should ignore it, but StateB::transition can extract the parameter a from it.

    This will have the biggest impact on your current framework implementation, but it could be sensible when different State subclasses require different forms of extra parameters. There are some different design alternatives for ExtraParameters possible, you have to think which abstraction may make most sense for your case.

What to choose depends on your real-world context, how many State types require what kind of parameters, and where and when the parameters are become available in the system, and where or how often they change - that is something only you know, since you left no clue about it in this question.

The extra parameter will only make sense in a code section where it clear that it is a specific parameter for a StateB object. Let me call this "application layer".

Your state pattern implementation, especially the classes Context and State, however, live inside some "framework layer", which does not know anything about the specific StateB and it's requirements for an extra parameter.

The straightforward solution here is to make the parameter a a member of the class StateB, which has to be initialized before Context::transition() (inside the framework layer) is called. The initialization has to happen somewhere inside the application layer. You have basically the following options for this:

  • pass the initial parameter value in the StateB constructor - that requires each constructor call to look like new StateB(context,initialA). That's feasible when initialA is available at all places where new StateB is called.

  • provide an extra setter method StateB::setA(int initialA) and call it somewhere in the application layer, where it is appropriate. That may require detection of when Context::current is of type StateB and a downcast

In case you don't want this extra member variable, you can also try this:

  • create a generalization of "potentially extra parameters" in the framework layer, for example, an ExtraParameters class, and extend the signature of State::transition and Context::transition by this ExtraParameters. All states which don't need this parameter should ignore it, but StateB::transition can extract the parameter a from it. This will have the biggest impact on your current framework implementation, but it could be sensible when different State subclasses require different forms of extra parameters.

What to choose depends on your real-world context, how many State types require what kind of parameters, and where and when the parameters are available in the system - that is something only you know, since you left no clue about it in this question.

The extra parameter will only make sense in a code section where it clear that it is a specific parameter for a StateB object. Let me call this "application layer".

Your state pattern implementation, especially the classes Context and State, however, live inside some "framework layer", which does not know anything about the specific StateB and it's requirements for an extra parameter.

The straightforward solution here is to make the parameter a a member of the class StateB, which has to be initialized before Context::transition() (which is part of the framework layer) is called. The initialization has to happen somewhere inside the application layer. You have basically the following options for this:

  • Pass the initial parameter value in the StateB constructor - that requires each constructor call to look like new StateB(context,initialA). That's feasible when initialA is available at all places and at the time where new StateB is called.

  • Provide an extra setter method StateB::setA(int initialA) and call it somewhere in the application layer, before Context::transition happens. That may require detection of when Context::current is of type StateB and a downcast. It also has some risk to be forgotten to be called and it gives StateB some mutable state.

In case you don't want to introduce this extra member variable, you can also try this:

  • Create an abstraction for "potentially extra parameters" in the framework layer, for example, an ExtraParameters class, and extend the signature of State::transition and Context::transition by this ExtraParameters. All states which don't need this parameter for a transition should ignore it, but StateB::transition can extract the parameter a from it.

    This will have the biggest impact on your current framework implementation, but it could be sensible when different State subclasses require different forms of extra parameters. There are some different design alternatives for ExtraParameters possible, you have to think which abstraction may make most sense for your case.

What to choose depends on your real-world context, how many State types require what kind of parameters, and where and when the parameters are become available in the system, and where or how often they change - that is something only you know, since you left no clue about it in this question.

Source Link
Doc Brown
  • 220.7k
  • 35
  • 411
  • 625

The extra parameter will only make sense in a code section where it clear that it is a specific parameter for a StateB object. Let me call this "application layer".

Your state pattern implementation, especially the classes Context and State, however, live inside some "framework layer", which does not know anything about the specific StateB and it's requirements for an extra parameter.

The straightforward solution here is to make the parameter a a member of the class StateB, which has to be initialized before Context::transition() (inside the framework layer) is called. The initialization has to happen somewhere inside the application layer. You have basically the following options for this:

  • pass the initial parameter value in the StateB constructor - that requires each constructor call to look like new StateB(context,initialA). That's feasible when initialA is available at all places where new StateB is called.

  • provide an extra setter method StateB::setA(int initialA) and call it somewhere in the application layer, where it is appropriate. That may require detection of when Context::current is of type StateB and a downcast

In case you don't want this extra member variable, you can also try this:

  • create a generalization of "potentially extra parameters" in the framework layer, for example, an ExtraParameters class, and extend the signature of State::transition and Context::transition by this ExtraParameters. All states which don't need this parameter should ignore it, but StateB::transition can extract the parameter a from it. This will have the biggest impact on your current framework implementation, but it could be sensible when different State subclasses require different forms of extra parameters.

What to choose depends on your real-world context, how many State types require what kind of parameters, and where and when the parameters are available in the system - that is something only you know, since you left no clue about it in this question.