I'm trying to build a GraphBot class that can answer different questions about about an associated graph such as path length, shortest path between two vertices, number of paths passing through a given vertex etc.
I'd like to be able to add new questions without changing any code inside the Bot, it is only responsible for receiving the question, delegating so some other algorithm to solve the question using the graph associated with the bot and returning the answer.
So something like this:
public class GraphBot {
private Graph graph;
public GraphBot(Graph graph) {
this.graph = graph;
}
public Answer ask(Question question) {
// delegate somehow to answer the question, providing the graph
// return an Answer object encapsulating the answer
}
}
public interface Answer {
public toPrintableOutput();
}
public interface Question {
// question methods go here... this is what I'm having trouble with
}
The trouble I'm having is that questions have associated conditions or parameters. For instance, the question "path length" between "A" and "B" has the question type ("path length") which is something all questions will have, but also the parameters "A" and "B". In comparison, the question "paths passing through vertex" will only have the parameter "C" representing the vertex.
I can't think of a way of presenting a uniform interface so that the system can be easily extended to handle numerous different questions with different numbers and types of parameters. I could have a QuestionSolver that was associated with each Question in which case it wouldn't matter if each Question had different attributes as the QuestionSolver could assert that the question is of a valid type but this would require a mapping of Question to QuestionSolver somewhere that would require updating whenever a new question is introduced.
What is the most extensible way of implementing this system so that new questions would not require tonnes of changes in loads of different classes? Really I want to be able to create an class implementing Question and maybe create a class that can solve that question and then have the GraphBot automatically able to handle that question.