Hi,
I'm using the delegator pattern as part of the AI for a strategy game I'm writing in C++. The details of the game are unimportant. All you need to know is that there are various game states that come up while playing, and I need to handle each one differently. What's more, as my code evolves, I will need to add new games states that I hadn't thought of (dealing with more and more specific cases)....
The delegator class has only two relevant methods:
void add(Condition* condition, GameState* gamestate);
Action getNextAction();
The delegator will loop through the conditions (which can be thought of as describing game states), and find a gamestate which matches the current condition. The delegator will then delegate its "getNextAction()" to the gamestate's "getNextAction()" method. The gamestate object will then return an action.
This part of the design I am happy with. My problem is with the specifics of how I've handled the conditions. I have a condition class, with a virutal "isTrue()" method. I then subclass the Condition class to create the concrete condition classes that correspond to game states. But these concrete condition classes only need to be created once, and also should be globally accessbile. To answer both these requirements, I've created a convenience class call "Cond" that looks like this:
class Cond {
public:
static ConcreteCondition1 concreteCondition1;
static ConcreteCondition2 concreteCondition2;
static ConcreteCondition3 concreteCondition3;
//and so on
};
Now, the benefit of this is that I can write statements like this:
delegator_->add(&Cond::con
creteCondi
tion1, new GameStateForCondition1());
On the other hand, every time I create a new condition, I must not only create a new condition class, but also remember to add a static instance of that class to "Cond". I'm not sure if this is bad design or not, but something about it does not sit right with me.
In addition, the condition classes themselves all simply implement the single "isTrue" method -- thus, they exist merely as a formalism for containing a function, so that I can pass object around rather than passing pointers to functions around. This seems reasonable, but I wasn't entirely sure about that design decision either.
I'm looking for general comments about the effectiveness of this design. Any and all feedback will be much appreciated!