Я изучил, как работают дженерики, и нашел следующее решение:
Сначала я создал два класса, один для выражения и один для манипулятора:
public class ObjectExpression { }
public class ObjectManipulator <E extends ObjectExpression> {
public void calculate(Set<E> objects) {
... // Do something
}
}
Затем я создал класс Algorithm, который является общим.
Требуются два класса:
Некоторое выражение
То, что манипулирует этим типом объекта
Получаем:
public class Algorithm <F extends ObjectExpression, E extends ObjectManipulator<F>> {
E om;
public Algorithm( E om ) {
this.om = om;
}
public void run(Set<F> objects) {
om.calculate(objects);
}
}
Затем я создал реализацию для случая String:
нам нужно выражение и манипулятор
public class StringExpression extends ObjectExpression {
}
public class StringManipulator extends ObjectManipulator<StringExpression> {
@Override
public void calculate(Set<StringExpression> objects) {
// Do String stuff
}
}
Затем мы можем запустить алгоритм для объектов следующим образом:
Algorithm<ObjectExpression, ObjectManipulator<ObjectExpression>> algo1 = new Algorithm<ObjectExpression, ObjectManipulator<ObjectExpression>>(manipo);
Set<ObjectExpression> objects = new HashSet<ObjectExpression>();
... // fill set
algo1.run(objects);
и для строк:
StringManipulator manips = new StringManipulator();
Algorithm<StringExpression, StringManipulator> algo2 = new Algorithm<StringExpression, StringManipulator>(manips);
Set<StringExpression> strings = new HashSet<StringExpression>();
... // fill set
algo2.run(strings);
Мне это кажется элегантным решением.
Как вы думаете?
Любые альтернативы / улучшения?