Java Reference
In-Depth Information
public class VisitorTest {
public static void main(String[] args) {
Book[] books = new Book[]{
new AudioBook(), new FictionBook(), new FictionBook(),
new NonFictionBook(), new AudioBook(), new NonFictionBook()
};
List<AudioBook> audioBooks = new ArrayList<>();
List<FictionBook> fictionBooks = new ArrayList<>();
List<NonFictionBook> nonFictionBooks = new ArrayList<>();
for (Book book : books) {
if (book instanceof AudioBook)
audioBooks.add((AudioBook) book);
else if(book instanceof FictionBook)
fictionBooks.add((FictionBook) book);
else if(book instanceof NonFictionBook)
nonFictionBooks.add((NonFictionBook) book);
}
System.out.println("Nr. audio books: "+audioBooks.size());
System.out.println("Nr. fiction books: "+fictionBooks.size());
System.out.println("Nr. non-fiction books: "+nonFictionBooks.size());
}
}
However, there are a number of problems with this code. It's kind of ugly looking with all the type-
casting going on, and you realize that adding new types of books will require you to do a search for
all places where you do something like this.
Luckily, the visitor pattern can help you separate your algorithm (categorizing a list of books in
separate lists) from the data structure (the abstract class and its dependents). How? First of all, you
define an interface for a “visitor,” in this case, someone who can visit books like so:
public interface BookVisitor {
public void visit(AudioBook book);
public void visit(FictionBook book);
public void visit(NonFictionBook book);
}
Next, add a method to your Book class so that it can accept visitors, as well as to all the concrete
classes:
public abstract class Book {
private String title;
// ...
abstract public void accept(BookVisitor visitor);
}
public class FictionBook extends Book {
@Override
public void accept(BookVisitor visitor) {
Search WWH ::




Custom Search