I’m implementing classes for simulating and generating different kind of automata. I’d prefer to use the same State and Transition classes for all the automata: NFA, DFA, PDA, etc.
For a PDA a transition from one state to another work require some sort of an extension, because the transition requires to pop something from and push something on the stack.
So I came up with the idea to let the transitions accept a extension class as template parameter:
public class Transition<T> {
private State target;
private T extension;
public Transition(State target, T extension) {
this.target = target;
this.extension = extension;
}
public State getTarget() {
return target;
}
public T getExtension() {
return extension;
}
}
Note that there are EpsilonTransition
and RegularTransition
derived classes from this base class.
A PDA would require for instance this extension:
public class StackExtension {
private Character toPop, toPush;
public StackExtension(Character toPop, Character topush) {
this.toPop = toPop;
this.toPush = topush;
}
public Character getToPop() {
return toPop;
}
public Character getToPush() {
return toPush;
}
}
So that the PDA
class can use Transition<StackExtension>
instances.
Although this is a solution for my problem, it feels like bad design. Especially for the NFA and DFA, which do not require any extension.
Is there another design pattern for my particular problem?
0
I’m not familiar with the particular automata classes you mention, but whenever you have a one-off class that you’d like to handle in similarly to the other classes, then the Facade pattern is pretty useful.
I’m over-simplifying, but the facade pattern is little more than a wrapper around the class in order to either or both of:
- reduce the complexity of the available class methods
- make the class conform to a particular interface
In your case, it sounds like you’re wrapping the PDA
class so that it will conform to a particular set of interfaces. That’s a perfect use for the facade.
All the actual code you’ve shown doesn’t do anything, it just sets up properties, so any answer will involve some guessing.
It’s not clear to me why having an unconstrained generic type on transition makes sense. Could it take a string type? My guess is that what you are trying to do is let the “extension” class know that the transition has occurred, and perhaps some information about it.
That sounds kind of like the transition should emit a TransitionComplete event – except that events can be subscribed to by any class, making it difficult for someone reading the code to know where the event is actually consumed.
In your case, it might be more transparent if you passed your extension class in to the constructor of the of the transition class, of type ITransitionHandler, and called its TransitionComplete method.
I can’t say which is better for your program.
It’s possible to follow either of my suggestions and still make the Transition class generic, just constrained to ITransitionHandler only. But, why? The only class that really cares about the extension class’s type is the extension class itself, and it already knows. So why make that part of Transition’s type?
Again, without seeing your implementation, that may not be true, and making extension generic may be useful.
As an aside, I wouldn’t spend a huge amount of time perfecting the design. The number of automata types isn’t likely to grow very fast, and the amount of code with visibility into the details of this design is likely pretty small.