State pattern: Which class should I trust to update the state? [closed]
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this questionI am learning design pattern by reading Head First Design Patterns, and I have just finished the chapter on the State Pattern. However, there is one thing I don't get:
In the book, the class which has a state is called the Context, while the actual states implement the State interface. When a request is given the book use the method here to change the state:
- The Context receives the request;
- The Context call the handle() method on the State it has, hand the request to the State;
- The State process the request, and set the State in the Context if it should change. To do this, the States have the Context as a field.
However, this seems to me give a somewhat "recursive" coupling between the two class, and is unintuitive. I would prefer the following design if I haven't read their solution:
- The Context receives the request;
- The Context call the handle() method on the State it has, hand the request to the State;
- The State process the request, and return a State; whether it is another State depends on how the request is processed.
- The Context set its own State to the State returned.
The Pros and Cons I could think of:
- If we put all that can vary into the State classes, the Context and State and become more decoupled, since they won't need to peek into each others' fields;
- The State classes might become bigger;
- The State might 开发者_StackOverflow中文版not be easily reused among different Contexts. However, we could implement States as abstract classes that implement the State interface, and have concrete States that are used by Contexts subclassing the abstract States.
Is there any specific reason that the first one (which is used by Head First Design Patterns) should be favored, or the second choice is also valid and used in practice, or maybe it has some serious flaws that I did not see?
Thanks for all the inputs and for your time reading and replying!
The issue with the approach you mention is that any other objects which have a reference to the State object fail to get updates in the scenario you describe. As you describe it, the State can return another State which has the updated State, and the Context can replace its reference to a State with the updated State, but any other objects that have reference to the State will now have a dangling reference that's not referred to by Context.
There is a third way, instead of having the context as a member of the state, implement the state as a singleton pattern and pass the context as a parameter to the state's event member function. This is the same technique used in the flyweight pattern. That way, it is possible to use a colony of contexts, but only one instance of each state.
精彩评论