Представляют операцию, которая должна быть выполнена над элементами структуры объекта. Посетитель позволяет определить новую операцию без изменения классов элементов, с которыми она работает.
- Посетитель: объявляет операцию посещения для каждого класса конкретного элемента в структуре объекта. Имя и подпись операции идентифицируют класс, который отправляет посетителю запрос на посещение. Это позволяет посетителю определить конкретный класс посещаемого элемента. Затем посетитель может получить доступ к элементам непосредственно через свой особый интерфейс
- Конкретный посетитель: реализует каждую операцию, объявленную Посетителем. Каждая операция реализует фрагмент алгоритма, определенного для соответствующего класса или объекта в структуре. ConcreteVisitor предоставляет контекст для алгоритма и сохраняет его локальное состояние. Это состояние часто накапливает результаты во время обхода структуры.
- Элемент: определяет операцию принятия, которая принимает посетителя в качестве аргумента.
- Конкретный элемент: реализует операцию принятия, которая принимает посетителя в качестве аргумента
- Структура объекта: может перечислять его элементы. Может предоставлять интерфейс высокого уровня, позволяющий посетителю посещать его элементы. Может быть либо составным (шаблоном), либо коллекцией, такой как список или набор
public class Main { public static void main(String[] args) { ObjectStructure o = new ObjectStructure(); o.attach(new ConcreteElementA()); o.attach(new ConcreteElementB()); ConcreteVisitor1 v1 = new ConcreteVisitor1(); ConcreteVisitor2 v2 = new ConcreteVisitor2(); o.accept(v1); o.accept(v2); } } public interface Visitor { void visitConcreteElementA(ConcreteElementA concreteElementA); void visitConcreteElementB(ConcreteElementB concreteElementB); } public class ConcreteVisitor1 implements Visitor { @Override public void visitConcreteElementA(ConcreteElementA concreteElementA) { System.out.println( concreteElementA.getClass().getSimpleName() + " visited by " + this.getClass().getSimpleName()); } @Override public void visitConcreteElementB(ConcreteElementB concreteElementB) { System.out.println( concreteElementB.getClass().getSimpleName() + " visited by " + this.getClass().getSimpleName()); } } public class ConcreteVisitor2 implements Visitor { @Override public void visitConcreteElementA(ConcreteElementA concreteElementA) { System.out.println( concreteElementA.getClass().getSimpleName() + " visited by " + this.getClass().getSimpleName()); } @Override public void visitConcreteElementB(ConcreteElementB concreteElementB) { System.out.println( concreteElementB.getClass().getSimpleName() + " visited by " + this.getClass().getSimpleName()); } } public interface Element { void accept(Visitor visitor); } public class ConcreteElementA implements Element { @Override public void accept(Visitor visitor) { visitor.visitConcreteElementA(this); } public void operationA() { } } public class ConcreteElementB implements Element { @Override public void accept(Visitor visitor) { visitor.visitConcreteElementB(this); } public void operationB() { } } public class ObjectStructure { private Listelements = new ArrayList<>(); public void attach(Element element) { elements.add(element); } public void detach(Element element) { elements.remove(element); } public void accept(Visitor visitor) { for (Element element : elements) { element.accept(visitor); } } }
ConcreteElementA visited by ConcreteVisitor1 ConcreteElementB visited by ConcreteVisitor1 ConcreteElementA visited by ConcreteVisitor2 ConcreteElementB visited by ConcreteVisitor2
eidherjulian61/дизайн-шаблоны
Основные шаблоны Проектирования
ид ・ 27 сентября ・ 1 минута чтения
Оригинал: “https://dev.to/eidher/visitor-pattern-nfp”