nobody
nobody

Reputation: 1949

Overloaded method dispatching, without visitor pattern

I wanted to do overloaded method dispatching and Visitor pattern looked too much convoluted.

My stupid mind came up with something like below, and it works. Is it fine to follow something like this ?

An interface

  public interface Value {    
        default public Integer getValue(){
          return 1;
        }
  }

One can have multiple types of Value interface, for example like two Value interface implementations below.

 class ConcreteValueA implements Value {
     @Override
     public Integer getValue() {
         return 2;
     }
 }

class ConcreteValueB implements Value {
    @Override
    public Integer getValue() {
        return 3;
    }
 }

and a service implementation with overloaded methods like below which perform operations based on input type.

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"));
    }
 }

Prints 3:B, which what I wanted.

Upvotes: 2

Views: 327

Answers (1)

Jose Luis Martin
Jose Luis Martin

Reputation: 10709

Yes, Double Dispatch via reflection is a common replacement of the Visitor pattern in Java (and other languages that support introspection).

However, the Visitor pattern is still useful to let users to extend closed hierarchies, ie add a new virtual function to all classes of a hierarchy without changing them.

Upvotes: 2

Related Questions