[Design Pattern] 23, Visitor Pattern

(23) Visitor Mode

The Visitor Pattern is a design pattern that separates data structures from data manipulation.

1. The design principles of the visitor pattern

1. Abstract visitor (IVisitor): an interface or abstract class that defines a visit() method;

2. ConcreateVisitor: Operation of specific elements;

3. Abstract element (IElement): define a method accept() that receives visitor access;

4. ConcreateElement: Receive the specific implementation of the visitor;

5. ObjectStructure: Internally maintains a collection of elements and accepts access to all elements.

2. Simple case

Take the performance evaluation of engineers and managers by CTO and CEO respectively. The CTO cares about the engineer's code quality and the manager's number of new products, the CEO cares about the engineer's KPI, the manager's KPI, and the manager's number of new products.

public abstract class Employee {
    
    
    public String name;
    public int kpi;

    public Employee(String name){
    
    
        this.name = name;
        kpi = new Random().nextInt(10);
    }

    /**
     * 接受访问者访问
     * @param visitor 访问者接口
     */
    public abstract void accept(IVisitor visitor);
}
public class Engineer extends Employee {
    
    

    public Engineer(String name) {
    
    
        super(name);
    }

    @Override
    public void accept(IVisitor visitor) {
    
    
        visitor.visit(this);
    }
    public int getCodeLine(){
    
    
        return new Random().nextInt(10*1000);
    }
}
public class Manager extends Employee {
    
    
    public Manager(String name) {
    
    
        super(name);
    }

    @Override
    public void accept(IVisitor visitor) {
    
    
        visitor.visit(this);
    }
    public int getProducts(){
    
    
        return new Random().nextInt(10);
    }
}
public interface IVisitor {
    
    
    /**
     * 访问工程师
     * @param engineer
     */
    void visit(Engineer engineer);

    /**
     * 访问经理
     * @param manager
     */
    void visit(Manager manager);
}
public class CEOVisitor implements IVisitor {
    
    
    @Override
    public void visit(Engineer engineer) {
    
    
        System.out.println(engineer.name+" kpi为"+engineer.kpi);
    }

    @Override
    public void visit(Manager manager) {
    
    
        System.out.println(manager.name+" kpi为"+manager.kpi+" 产品数为"+manager.getProducts());
    }
}
public class CTOVisitor implements IVisitor {
    
    
    @Override
    public void visit(Engineer engineer) {
    
    
        System.out.println(engineer.name+" 代码量为"+engineer.getCodeLine());
    }

    @Override
    public void visit(Manager manager) {
    
    
        System.out.println(manager.name+" 产品数为"+manager.getProducts());
    }
}
public class BusinessReport {
    
    
    private List<Employee> employees = new LinkedList<Employee>();

    public BusinessReport(){
    
    
        employees.add(new Manager("A经理"));
        employees.add(new Manager("B经理"));
        employees.add(new Engineer("C工程师"));
        employees.add(new Engineer("D工程师"));
    }

    /**
     * 报表展示
     * @param visitor
     */
    public void showReport(IVisitor visitor){
    
    
        for(Employee employee : employees){
    
    
           employee.accept(visitor);
        }
    }
}
public class Client {
    
    
    public static void main(String[] args) {
    
    
        BusinessReport businessReport = new BusinessReport();
        System.out.println("CEO查看报表:");
        businessReport.showReport(new CEOVisitor());
        System.out.println("CTO查看报表");
        businessReport.showReport(new CTOVisitor());
    }
}

image-20210330191753656

3. Simple Comments on Visitor Mode

The class corresponding to an object in the object structure rarely changes, but it is often necessary to define new operations on this object structure. 2. Many different and unrelated operations need to be performed on objects in an object structure, and it is necessary to avoid letting these operations "pollute" the classes of these objects, and do not want to modify these classes when adding new operations.

Guess you like

Origin blog.csdn.net/qq_40589204/article/details/119914835