Should the strategy pattern be stateless?
Asked Answered
R

5

10

Must a class that is a "gang of four" strategy be completely stateless (ie no fields) or can it contain immutable state (ie final fields)?

Reflate answered 30/5, 2011 at 13:23 Comment(2)
why would the strategy pattern require state? It's job is to return some 'pluggable' functionalityAdversative
If you had a logging strategy and the "briefLoggingStrategy" was "If i've seen this message before I'll output "ditto" ... otherwise the whole message" ... then your strategy would have to hold state.Finnell
T
18

A strategy class encapsulates an action, not a thing. So although you could if you really had to, it wouldn't make a lot of sense to keep state in it. Think of it as a verb, not a noun. Or at least as a noun that describes an action. On the other hand, you could always parametrize the strategy and pass the state of the client object to it by method call or similar.

Also, whether a class is stateless or statefull doesn't really depend on the final keyword on its fields. Examples:

  • When used on objects final only means that the reference to an object may not be changed. You can still change the contents of that object, like its fields. In that case, your class is statefull although its field is final.
  • If the field really is a constant, then for most intents and purposes you can consider it stateless. For example, you can declare a field private static final and then make sure you never do anything to change the state of the referenced object.

EDIT: Let's try to distinguish between parameters of strategy itself and parameters of one particular execution of that strategy. If the strategy class is stateless then there is no point in having more than one instance of that class, which makes the object, not the class, represent the action itself and a method execution represent one particular execution of that strategy.

Now, if we have a parameter of the strategy itself it only makes sense that the parameter has the same value for all executions of that strategy. So, it can be placed in a constant, method call that returns a constant (if we don't wan't static stuff), or even hardcoded. As explained above, that can be implemented in the stateless way.

On the other hand, if the parameter describes one particular execution of the strategy, then just pass it as a parameter to the method. It will do.

Additional note: There is a good reason to use action objects with 'adverbs' packed in its state if we want to, say, have some kind of action queue of execution with delay, scheduling... There's a pattern for that too - Command.

Tuddor answered 30/5, 2011 at 13:35 Comment(3)
Not that I disagree with you (on the contrary, in fact... +1!), but I think it's significant to note that even verbs/actions have descriptors. If you're thinking of a stateful object as a noun, then it essentially has adjectives. Similarly, even if your strategy class encapsulates an action or a verb, you can hypothetically still utilize "adverbs" to detail the specifics of that action.Jibe
@JMTyler: I've never thought of action parameters as adverbs. Thanks for that analogy! See my edit for reply.Tuddor
Cool! I haven't heard of the Command pattern before, thanks for pointing that out!Jibe
S
6

No, why should it be stateless? The strategy could be anything, it simply represents some runtime pluggable unit of functionality that allows you to extend the modify the behaviour of the consuming class. There is nothing, as far as I know, that suggests the requirement of statelessness, nor immutability.

Sauder answered 30/5, 2011 at 13:27 Comment(2)
Are you saying that a strategy is just a delegate then?Reflate
Now we're into semantics. Yes in the broadest sense of the meaning of the word 'delegate', no in the concrete .NET sense.Sauder
P
5

Statelessness refers to the fact that no data is preserved between runs of a strategy; i.e. if you execute the same strategy twice, nothing from the previous run of the strategy would carry over. This is beneficial in that it saves you the trouble of having to "reset" your Strategy implementations when needed.

Note that in the description of the Strategy pattern implementation they make reference to a Context (@ page 317 in my book) that contains the data the strategy needs to execute. All the 'state' required by the implementations should probably go in these context objects.

This means that the strategy implementations themselves are stateless, but the pattern as a whole has state as the required data is passed around in a context.

For example, if you had strategy implementations for mathematical operations, there are at least 2 ways to do it. The first would be to set arg1 and arg2 (and 3, and 4...) on the strategy implementations when you construct them. Then when you execute the implementation would grab its fields and do the operation. The problem is, if you run the same implementation again, you have to reset all its fields (or create a new implementation).

The second way would be to create a context that contains all the arguments. The stategy implementations would grab the values it needs off the context. Then you could reuse each instance of your strategy implementation, just passing a new context each time. No worry about recreating new instances of the implementations, or forgetting to reset the implementation instance. Of course, you still need to manage the contexts correctly.

Papke answered 30/5, 2011 at 13:32 Comment(1)
If you had a logging strategy and the "briefLoggingStrategy" was "If i've seen this message before I'll output "ditto" ... otherwise the whole message" ... then your strategy would have to hold state.Finnell
F
3

The intent of the strategy pattern is to work on the strategy method arguments directly in the method local scope. The strategy class itself can of course hold some fields whenever required, but the method arguments should in no way be assigned to those fields as it can introduce threadsafety problems if the strategy object is used more than once.

Fearless answered 30/5, 2011 at 13:31 Comment(0)
K
0

Yes, as this is algorithm chooser mostly. Concrete algorithm can have state, but not the chooser.

By the way in this strategy we don't have one class. Which concrete class do you mean? In what role?

Kinnikinnick answered 30/5, 2011 at 13:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.