Strategy pattern and "action" classes explosion
- by devoured elysium
Is it bad policy to have lots of "work" classes(such as Strategy classes), that only do one thing?
Let's assume I want to make a Monster class. Instead of just defining everything I want about the monster in one class, I will try to identify what are its main features, so I can define them in interfaces. That will allow to:
Seal the class if I want. Later, other users can just create a new class and still have polymorphism by means of the interfaces I've defined. I don't have to worry how people (or myself) might want to change/add features to the base class in the future. All classes inherit from Object and they implement inheritance through interfaces, not from mother classes.
Reuse the strategies I'm using with this monster for other members of my game world.
Con: This model is rigid. Sometimes we would like to define something that is not easily achieved by just trying to put together this "building blocks".
public class AlienMonster : IWalk, IRun, ISwim, IGrowl {
IWalkStrategy _walkStrategy;
IRunStrategy _runStrategy;
ISwimStrategy _swimStrategy;
IGrowlStrategy _growlStrategy;
public Monster() {
_walkStrategy = new FourFootWalkStrategy();
...etc
}
public void Walk() { _walkStrategy.Walk(); }
...etc
}
My idea would be next to make a series of different Strategies that could be used by different monsters. On the other side, some of them could also be used for totally different purposes (i.e., I could have a tank that also "swims"). The only problem I see with this approach is that it could lead to a explosion of pure "method" classes, i.e., Strategy classes that have as only purpose make this or that other action. In the other hand, this kind of "modularity" would allow for high reuse of stratagies, sometimes even in totally different contexts.
What is your opinion on this matter? Is this a valid reasoning? Is this over-engineering?
Also, assuming we'd make the proper adjustments to the example I gave above, would it be better to define IWalk as:
interface IWalk {
void Walk();
}
or
interface IWalk {
IWalkStrategy WalkStrategy { get; set; } //or something that ressembles this
}
being that doing this I wouldn't need to define the methods on Monster itself, I'd just have public getters for IWalkStrategy (this seems to go against the idea that you should encapsulate everything as much as you can!)
Why?
Thanks