Visitor pattern

What is the Visitor pattern?

Separate data structure and processing. Prepare a class that represents the visitors who roam the data structure, and let that class handle the processing. The data structure side will accept visitors.

The role of a visitor

The Visitor role is said to have "visited xxx" for each specific element of the data structure (ConcreteElement role). Declare the visit (xxx) method. visit (xxx) is a method for processing xxx, and the actual code is written on the side of the Concrete Visit role.

package visitor;

public abstract class Visitor {
	public abstract void visit(File file);
	public abstract void visit(Directory directory);
}

The role of Concrete Visitor

The ConcreteVisitor role implements the Visitor role interface. Implement a method in the form of visit (xxx) and describe the processing for each ConcreteElement role.

package visitor;

import java.util.Iterator;

public class ListVisitor extends Visitor{
	private String currentDir = "";

	@Override
	public void visit(File file) {
		System.out.println(currentDir + "/" + file);
	}

	public void visit(Directory directory) {
		System.out.println(currentDir + "/" + directory);
		String savedDir = currentDir;
		currentDir = currentDir + "/" + directory.getName();
		Iterator<Entry> it = directory.iterator();
		while (it.hasNext()) {
			Entry entry = it.next();
			entry.accept(this);
		}
		currentDir = savedDir;
	}
}

The role of Element

The role of Element is a role that represents the destination of the role of Visitor. Declare an accept method that accepts visitors. The Visitor role is passed to the argument of the accept method.

package visitor;

public interface Element {
	public abstract void accept(Visitor v);
}

The role of Concrete Element

The ConcreteElement role is the role that implements the interface of the Element role.

package visitor;

public class File extends Entry{
	private String name;
	private int size;

	public File(String name, int size) {
		this.name = name;
		this.size = size;
	}

	public String getName() {
		return name;
	}

	public int getSize() {
		return size;
	}

	@Override
	public void accept(Visitor v) {
		v.visit(this);
	}
}
package visitor;

import java.util.ArrayList;
import java.util.Iterator;


public class Directory extends Entry{
	private String name;
	private ArrayList<Entry> directory = new ArrayList<>();

	public Directory(String name) {
		this.name = name;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public int getSize() {
		int size = 0;
		Iterator<Entry> it = directory.iterator();
		while (it.hasNext()) {
			Entry entry = (Entry) it.next();
			size += entry.getSize();
		}
		return size;
	}

	public Entry add(Entry entry) {
		directory.add(entry);
		return this;
	}

	public Iterator<Entry> iterator() {
		return directory.iterator();
	}

	public void accept(Visitor v) {
		v.visit(this);
	}
}

The role of Object Structure

The Object Structure role is a role that handles a set of Element roles. It has a method that allows the ConcreteVisitor role to handle individual Element roles. This role corresponds to the above Directory class.

Caller

package visitor;

public class Main {
	public static void main(String[] args) {
		try {
			System.out.println("Making root entries...");
			Directory rootDir = new Directory("root");
			Directory binDir = new Directory("bin");
			Directory tmpDir = new Directory("tmp");
			Directory usrDir = new Directory("usr");
			rootDir.add(binDir);
			rootDir.add(tmpDir);
			rootDir.add(usrDir);
			binDir.add(new File("vi", 10000));
			binDir.add(new File("latex", 20000));
			rootDir.accept(new ListVisitor());

			System.out.println();
			System.out.println("Making user entryies...");
			Directory yuki = new Directory("yuki");
			Directory hanako = new Directory("hanako");
			Directory tomura = new Directory("tomura");
			usrDir.add(yuki);
			usrDir.add(hanako);
			usrDir.add(tomura);
			yuki.add(new File("diary.html", 100));
			yuki.add(new File("Composite.java", 200));
			hanako.add(new File("memo.tex", 300));
			tomura.add(new File("game.doc", 400));
			tomura.add(new File("junk.mail", 500));
			rootDir.accept(new ListVisitor());
		} catch (FileThreatmentException e) {
			e.printStackTrace();
		}
	}
}

Execution result

スクリーンショット 2020-09-16 18.12.57.png

https://github.com/aki0207/visitor

I used this as a reference. Augmented and Revised Introduction to Design Patterns Learned in Java Language

Recommended Posts

Visitor pattern
Visitor Pattern
Design pattern ~ Visitor ~
Memento Pattern
Mediator pattern
Iterator pattern
Composite pattern
Observer Pattern
Builder pattern
Bridge Pattern
Command Pattern
Strategy pattern
Iterator Pattern
Adapter Pattern
Proxy Pattern
Strategy Pattern
Composite Pattern
Singleton Pattern
Singleton pattern
Prototype Pattern
Facade Pattern
Decorator pattern
Flyweight Pattern
Decorator Pattern
Mediator Pattern
Facade pattern
Bridge pattern
abstract Factory Pattern
Design pattern ~ Builder ~
[Java] Strategy pattern
Java design pattern
java callback pattern
Design pattern ~ State ~
Design pattern ~ Strategy ~
Design pattern ~ Singleton ~
Design pattern ~ Composite ~
Design pattern (2): Builder
[Java] Singleton pattern
Design pattern ~ Command ~
Abstract Factory pattern
Design pattern ~ Iterator ~
Design pattern ~ Facade ~
Design pattern ~ Bridge ~
Design pattern ~ Mediator ~
Template Method pattern
Design pattern ~ Decorator ~
Template Method Pattern
Design pattern ~ Interpreter ~
Factory Method pattern
Design pattern ~ Observer ~
Design pattern ~ Prototype ~
[Java] Adapter pattern
Design pattern ~ Memento ~
Design pattern ~ Adapter ~
Design pattern ~ Flyweight ~
Java pattern memo