1

I have some doubts about the state pattern, but I think it is better to ask one question at a time, so it is easier to focus on the answer.

The state pattern establishes which actions can be performed according to the state. So, if the context is in state A, I can perform actions 1, 2, and 3, for example.

However, my doubt is what happens when the action depends on other variables. For example, I have a valve that can be opened and closed. But to open it, it is only possible if the pressure is below a certain value.

In this case, the action "Open()" not only depends on the state but also on other conditions, such as the pressure in this case.

Should I pass this variable to the state object and perform the action through the state? It may seem a bit confusing to perform all the actions through the state.

Furthermore, what happens if there are many other variables apart from the state? Suppose the action depends on the state and five other variables, for example. If I perform the action through the state, in some way, I am giving more importance to the state than the other variables, and perhaps it is not very intuitive.

Continuing with the valve example, suppose it is in the closed state and I want to open the valve. But it depends on the pressure, temperature, and type of operator (a worker can't open it, but a high-level operator can). Is this a case to use the state pattern, or is there a better option? If it is a good candidate for the state pattern, how could I implement it?

6
  • 1
    I took the freedom to ask ChatGPT to improve spelling, wording and grammar in this question, the result looks pretty good to me. That's an allowed usage of ChatGPT,
    – Doc Brown
    Jun 18 at 9:36
  • @DocBrown Thanks for that. It is a good idea to use ChatGPT for that, sometimes my english is not very good. Jun 18 at 10:54
  • To be honest, I used it also to improve wording, grammar and spelling (but not content!) of my answer.
    – Doc Brown
    Jun 18 at 10:55
  • we gona have a tag for AI generated?
    – Ewan
    Jun 18 at 13:30
  • @Ewan: I think "AI generated" would be misleading in this case, the original content was 100% human generated.
    – Doc Brown
    Jun 18 at 20:13

1 Answer 1

1

If you have an action like "Open" that requires additional data to be performed correctly, it is necessary to pass that data to the operation, regardless of whether the action is part of the "core" object (Valve) or a specific state object. The approach to achieving this depends on the specific case. The usual options include introducing additional parameters to the operation or utilizing member variables of the object to which the action belongs.

For instance, if "Open" is a method within the Valve object, the Valve object could maintain a reference to a Waterpipe object that contains information about the pressure, temperature, and other relevant aspects of the water behind the valve. In this scenario, the "Open" method can directly access these parameters through the Waterpipe object.

On the other hand, if "Open" is part of a ValveState object, one approach could be passing a reference to the Waterpipe object to the state object during construction. The state object can then store this reference in one of its own member variables. Alternatively, the Valve object can pass a reference to itself (using this) to the ValveState object during construction.

Your other doubts like

It may seem a bit confusing to perform all the actions through the state. Is this a case to use the state pattern, or is there a better option?

are unrelated to the way how the information is passed to the operation. They are related to the question if you should use the state pattern at all, or if this might be overengineered.

This is a question that cannot be answered solely by looking at artificial, contrived examples. My best recommendation in this situation is to initially start without using any design patterns, such as the state pattern. When the code base for your Valve class remains small, it is acceptable to keep all the operations within the class itself. However, as the code base grows over time and you find yourself dealing with 200 to 300 lines of code inside a class of over 1000 lines, solely focused on a particular state model, it becomes necessary to consider refactoring by introducing an additional class or class hierarchy for the states, potentially utilizing the state pattern.

Note that the size of the code is just a rough indicator. Other factors to consider include the desire to write unit tests in isolation for specific groups of states or the need to extend the list of states without modifying the Valve class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.