Я хотел сделать перегруженный метод отправки и шаблон посетителя выглядел слишком запутанным.
Мой глупый ум придумал что-то вроде ниже, и это работает. Хорошо ли следовать чему-то подобному?
Интерфейс
public interface Value {
default public Integer getValue(){
return 1;
}
}
Можно иметь несколько типов интерфейса Value, например, как две реализации интерфейса Value ниже.
class ConcreteValueA implements Value {
@Override
public Integer getValue() {
return 2;
}
}
class ConcreteValueB implements Value {
@Override
public Integer getValue() {
return 3;
}
}
и реализация службы с перегруженными методами, такими как ниже, которые выполняют операции на основе типа ввода.
public class ImplA implements Interface{
private final Function<ConcreteValueA, Optional<String>> handleConcreteA = this::handle;
private final Function<ConcreteValueB, Optional<String>> handleConcreteB = this::handle;
private final Map<Class<? extends Value>, Function> functions;
public ImplA(){
functions = new HashMap<>();
functions.put(ConcreteValueA.class, handleConcreteA);
functions.put(ConcreteValueB.class, handleConcreteB);
}
/**
* Overridden method
*/
@Override
public Optional<String> handle(Value input) {
Function function = functions.get(input.getClass());
return (Optional<String>)function.apply(input);
}
/**
* Overloaded method A
*/
public Optional<String> handle(ConcreteValueA input) {
return Optional.of(input.getValue()+":A");
}
/**
* Overloaded method B
*/
public Optional<String> handle(ConcreteValueB input) {
return Optional.of(input.getValue()+":B");
}
/**
* Test method
*/
public static void main(String [] args){
Interface service = new ImplA();
Value input = new ConcreteValueB();
Optional<String> optional = service.handle(input);
System.out.println(optional.orElse("Default"));
}
}
Печать 3: B, что я хотел.
Да, Double Dispatch через отражение является общей заменой шаблона Visitor в Java (и других языках, которые поддерживают интроспекцию).
Однако шаблон Visitor по-прежнему полезен, чтобы позволить пользователям расширять закрытые иерархии, т.е. добавлять новую виртуальную функцию ко всем классам иерархии без их изменения.