My application is an editor for connecting "modules" (through module ports). Ports have port types. Each port type has it's associated comparator. Two types are compatible if their attributes satisfy rules implemented in the comparator.
I want users to extend the application by implementing new port types and rules how to connect them (through the eclipse extension point infrastructure).
This implies that during runtime I can only interact with the port type interfaces. No concrete classes are known. All concrete implementations are returned by a factory.
I implemented this two interfaces:
public interface IPortType {
[many attributes]
}
public interface IComparator {
public boolean isCompatible(IPortType source, IPortType target);
// more interaction methods!
}
My current solution is a bit ugly, since the generic isCompatible(IPortType source, IPortType target) method is a kind of delegate and has to be rewritten in all subclasses. Simply overloading the isCompatible() method does not work here.
But a bigger disadvantage is the violation of the open-closed-principle: One must extend all concrete Comparator classes when a new type should be supported. But how to keep the number of rule classes low, when there are more interactions between types like conversion, etc.? My intention was to keep all rules for one type in one class.
A concrete Comparator example:
public class ATypeComparator implements IComparator {
public boolean isCompatible(IPortType source, IPortType target) {
if (!(source instanceof AType))
return false;
if (target instanceof BType)
return isCompatible(source, (BType) target);
if (target instanceof CType)
return isCompatible(source, (CType) target);
}
public boolean isCompatible(AType source, BType target) {...}
public boolean isCompatible(AType source, CType target) {...}
}
How would you solve this problem?
Thanks for any suggestions!