Visitor pattern with Java 8 default methods
Asked Answered
E

1

9

Visitor pattern (double dispatch) is a very useful pattern in its own rights, but it has often been scrutinized of breaking interfaces if any new member is added to the inheritance hierarchy, which is a valid point.

But after the introduction of default methods in Java 8, now that we can define default implementation in interfaces, the client interfaces will not break and clients can gracefully adopt the changed interface as appropriate.

interface Visitor{
   public void visit(Type1 type);
   public void visit(Type2 type);

   //added after the first version of visitor is released
   default public void visit(NewType type){
        //some default implementation
   }
}

Now with default methods no more breakage of client code if new type NewType is introduced in future.

Does this make Visitor more adoptable and useful?

Epiphenomenon answered 29/3, 2014 at 21:28 Comment(3)
I personally see the interface break as an advantage, most of the time, because it forces you to take care of the new type everywhere, without fearing to miss a place like you would with chains of instanceof tests. Implementing the new visit() method as a default method would provide a default implementation which, I guess, would be wrong in 99% of the cases. Who cares if the code still compiles, if you know it won't do what it should at runtime?Pony
@JBNizet Yes. Its just that visitor has this one disadvantage which I thought was no more applicable. But I see why one should not use default method with visitor.Epiphenomenon
I agree, the Visitor Pattern is IMO all about compile errors. If the code breaks not before runtime, aka. at the customer's, it is too late.Barnebas
N
4

Your question contains the implicit assertion that a Visitor has to be an interface. Since the Visitor pattern is not Java specific, it does not mandate such an implementation.

In fact, there are a lot of uses around the world using an abstract class for the Visitor or using an interface but providing an abstract implementation class at the same time.

While this comment has a valid point of the possibility to detect unhandled cases at compile time this applies only to the case where every visitor always has to provide implementations for every visit method. This can be quite a code bloat when you have a lot of cases (And may cause other developers to write their own abstract base class for their visitors).

As said, not everyone uses the Visitor pattern this way. A lot of implementations use abstract classes for providing empty visit methods or visit methods which delegate to another visit method taking a more abstract type. For these implementations, adding a new type never was an issue.

And, to answer your question, when using the Visitor pattern in a way not forcing every Visitor to provide an implementation for every method, using default methods in interfaces is an option. But it does not make the Visitor pattern “more adoptable and useful” as there never was a real problem with it. The option to use an abstract visitor class always existed.

Normandnormandy answered 13/5, 2014 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.