Мое приложение представляет собой редактор для подключения «модулей» (через порты модулей). Порты имеют типы портов. Каждый тип порта имеет свой компаратор. Два типа совместимы, если их атрибуты удовлетворяют правилам, реализованным в компараторе.
Я хочу, чтобы пользователи расширяли приложение, внедряя новые типы портов и правила их подключения (через инфраструктуру точек расширения eclipse).
Это означает, что во время выполнения я могу взаимодействовать только с интерфейсами типа порта. Конкретные классы неизвестны. Все конкретные реализации возвращаются фабрикой.
Я реализовал эти два интерфейса:
public interface IPortType {
[many attributes]
}
public interface IComparator {
public boolean isCompatible(IPortType source, IPortType target);
// more interaction methods!
}
Мое текущее решение немного уродливо, поскольку общий метод isCompatible(источник IPortType, цель IPortType) является своего рода делегатом и должен быть переписан во всех подклассах. Простая перегрузка метода isCompatible() здесь не работает.
Но большим недостатком является нарушение принципа открытого-закрытого: необходимо расширить все конкретные классы Comparator, когда должен поддерживаться новый тип. Но как сохранить небольшое количество классов правил, когда существует больше взаимодействий между типами, такими как преобразование и т. д.? Мое намерение состояло в том, чтобы сохранить все правила для одного типа в одном классе.
Конкретный пример компаратора:
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) {...}
}
Как бы вы решили эту проблему?
Спасибо за любые предложения!