Both here on stack overflow and on Java Effective it is suggested that strategy design patterns should be stateless. In fact in the book it is also suggested to make each strategy object a singleton.
The problem I have is that some strategies I envision for my program need states/fields. Either because they are path-dependent in their behavior or because I want them heterogeneous (a statistical distribution of similar strategies, if you prefer).
This forces me to break both Java Effective suggestions: I instantiate a new strategy for each user class AND each of these strategies contain its own fields.
Is that very bad? Should it be done differently?
It was suggested to me to keep the fields that make the strategy heterogeneous in the class that uses it and then pass it as an argument. I find that very anti-oo. Those fields don't belong to the user class. In fact, if that class uses another strategy it might not need those fields at all. That seems to run against the reason I am using the strategy pattern in the first place.
Mostly I am just very confused
I make a simple example here. Imagine you have a class Gambler, which represents somebody making bets on horses. Now this class will require a strategy predictStrategy that will work something like this:
interface predictStrategy{
public Horse predictWinningHorse(HorseRace r);
}
Now, I can have many implementations where the strategy is to choose at random, or pick the white horse or whatever. That's easy.
Imagine though that I implement a strategy that looks at past predictions and somewhat "learns" from its past mistakes. Clearly each strategy will have to have its own memory on which to learn. I might have to add one more method to the interface (or make an extension)
interface predictStrategy{
public Horse predictWinningHorse(HorseRace r);
public void addObservation(HorseRace r, Horse oldPrediction, Horse actualWinner);
}
So that the Gambler class calls "strategy.addObservation(...)" at the end of each race to improve its predictive power.
Can this be really be done with a stateless strategy object? It seems impossible to me.