Does Java 8 provide an alternative to the visitor pattern?
What's the difference between functional programming and object-oriented programming?
Say I have an animal interface:
public interface Animal { public void speak(); }
I have a dog, cat, fish and bird, all of which have implemented the interface If I want to add a new method named jump () for animal, I will have to pass all my subclasses and implement jump ()
Visitor mode can alleviate this problem, but it seems that new features have been introduced in Java 8. We should be able to solve this problem in different ways In Scala, I can easily use pattern matching, but Java doesn't really have it
Does Java 8 actually make it easier to add new operations to existing things?
Solution
The addition of the Java language will not make every old concept obsolete In fact, visitor mode is very helpful to support the addition of new operations
When comparing this pattern with the new Java 8 possibilities, the following becomes obvious:
>Java 8 allows you to easily define operations that contain a single function When dealing with things like Iterable forEach,Stream. forEach,Stream. When a planar uniform collection such as reduce is used, it is convenient for visitors to define multiple functions. These functions are selected by the element type and / or topology of the data structure. It becomes interesting when dealing with heterogeneous sets and non planar structures, such as when a single functional feature stops working Item tree
Therefore, the new Java 8 features will never be a substitute for the visitor pattern, but it is reasonable to look for possible synergies This answer discusses the possibility of improving the existing API (filevisitor) to enable the use of lambda expressions The solution is a specific visitor implementation, which can specify the corresponding functions for each access method If each function is optional (that is, each access method has a reasonable default value), it will be convenient if the application is interested in only a small number of possible operations, or if you want to deal with most of them uniformly
If some of these use cases are considered "typical", there may be acceptance methods to take one or more functions and create appropriate delegate visitors after the scenario (when designing new APIs or improving APIs under your control) However, I will not give up XYZ visitor, because the option of using the existing implementation of visitors cannot be underestimated
If we regard the collector as a visitor to the stream, there is a similar overload in the stream API It consists of up to four functions, which is the greatest imagination and can access a flat, homogeneous project sequence Instead of having to implement the interface, you can start reduction specifying a single function or mutable reduction using three functions, but generally, specifying an existing implementation is more concise. For example, collect (collectors. Tolist()) or collect (collectors. Joining (",") specify all necessary functions through lambda expression / method reference
When such support is added to a specific application in visitor mode, it will make the calling site more shiny, while the implementation site of a specific acceptance method is always simple So the only part that is still cumbersome is the visitor type itself; It may even become more complex when adding support for operations based on functional interfaces In the near future, it is impossible to have a language - based solution that makes it easier to create such visitors or replace the concept