Java Design Pattern 14-Visitor Pattern

visitor mode

This pattern is rarely used. The author of "Design Patterns" commented:

Most of the time, you don't need to use visitor mode, but when you need to use it, you really need to use it.

1. Requirements for evaluation systems

1) Divide the audience into men and women and evaluate the singer. After watching a singer's performance, get their different evaluations of the singer (there are different types of evaluations, such as success, failure, etc.)

image-20210703210110883

2. Problem analysis using traditional methods

1) If the system is relatively small, it is still ok, but when considering that the system adds more and more new functions, the code changes will be larger, which violates the OCP principle.不利于维护

2) 扩展性不好For example, adding new types of personnel or management methods are difficult to implement.

3) Introduce new design patterns we will use –访问者模式

image-20210703210126584

3. Basic introduction to visitor mode

1) Visitor Pattern encapsulates some operations that act on each element of a certain data structure. It can define new operations that act on these elements without changing the data structure.

2) Mainly separate data structures and data operations to 数据结构solve 操作耦合性problems

3) The basic working principle of the visitor mode is: add an interface to the visited class to provide an external interface for receiving visitors.

4) The main application scenario of the visitor pattern is: you need to perform many different operations on the objects in an object structure (these operations are not related to each other), and you need to avoid letting these operations "pollute" the classes of these objects. You can choose the visitor pattern to solve this problem.

4. Principle class diagram of visitor mode

image-20210703210817752

  • Explanation of the schematic class diagram - namely (roles and responsibilities of visitor mode)

1)Visitor: It is an abstract visitor, which declares a visit operation for each class of ConcreteElement in the object structure.

2) ConcreteVisitor: It is a specific visitor that implements each operation declared by Visitor, and is the specific implementation part of each operation.

3) ObjectStructure: can enumerate its elements and provide a high-level interface to allow visitors to access elements

4)Element: Define an accept method to receive a visitor object

5)ConcreteElement: For specific elements, the accept method is implemented

5. Application examples of visitor mode

1) Divide people into men and women, evaluate singers, and after watching a singer perform, get their different evaluations of the singer (there are different types of evaluations, such as success, failure, etc.), please use the visitor model to achieve

2) Idea analysis and illustration (class diagram)

image-20210703211735411

3) Code implementation

Action: abstract operation class, which contains abstract operation methods

public abstract class Action {
    
    
    //得到男性 的测评
    public abstract void getManResult(Man man);

    //得到女的 测评
    public abstract void getWomanResult(Woman woman);
}

main function

public class Client {
    
    
    public static void main(String[] args) {
    
    
        //创建 ObjectStructure
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.attach(new Man()); 
        objectStructure.attach(new Woman());

        //成功
        Success success = new Success(); 
        objectStructure.display(success);

        System.out.println("==============="); 
        Fail fail = new Fail(); objectStructure.display(fail);

        System.out.println("=======给的是待定的测评========");

        Wait wait = new Wait(); 
        objectStructure.display(wait);
    }
}

Fail

public class Fail extends Action {
    
    
    @Override
    public void getManResult(Man man) {
    
    
        System.out.println(" 男人给的评价该歌手失败 !");
    }

    @Override
    public void getWomanResult(Woman woman) {
    
    
        System.out.println(" 女人给的评价该歌手失败 !");
    }
}

Man

public class Man extends Person {
    
    
    @Override
    public void accept(Action action) {
    
    
        action.getManResult(this);
    }
}

ObjectStructure: data structure

//数据结构,管理很多人(Man , Woman) 
public class ObjectStructure {
    
    
    //维护了一个集合
    private List<Person> persons = new LinkedList<>();

    //增加到 list
    public void attach(Person p) {
    
    
        persons.add(p);
    }
    
    //移除
    public void detach(Person p) {
    
     
        persons.remove(p);
    }

    //显示测评情况
    public void display(Action action) {
    
     
        for(Person p: persons) {
    
    
            p.accept(action);
        }
    }
    
}

Person: abstract human being

public abstract class Person {
    
    
    //提供一个方法,让访问者可以访问
    public abstract void accept(Action action);
}

Success

public class Success extends Action {
    
    
    @Override
    public void getManResult(Man man) {
    
    
        System.out.println(" 男人给的评价该歌手很成功 !");
    }
    
    @Override
    public void getWomanResult(Woman woman) {
    
    
        System.out.println(" 女人给的评价该歌手很成功 !");
    }
}

Wait

public class Wait extends Action {
    
    
    @Override
    public void getManResult(Man man) {
    
    
        System.out.println(" 男人给的评价是该歌手待定 ..");
    }
    
    @Override
    public void getWomanResult(Woman woman) {
    
    
        System.out.println(" 女人给的评价是该歌手待定 ..");
    }
}

Woman

//说明
//1. 这里我们使用到了双分派,  即首先在客户端程序中,将具体状态作为参数传递 Woman 中(第一次分派)
//2. 然后 Woman 类调用作为参数的 "具体方法" 中方法 getWomanResult, 同时将自己(this)作为参数
//	传入,完成第二次的分派
public class Woman extends Person{
    
    
    @Override
    public void accept(Action action) {
    
    
        action.getWomanResult(this);
    }

}

6. Precautions and details of visitor mode

  • advantage

1) The visitor model conforms to the single responsibility principle, allowing the program to have excellent scalability and very high flexibility.

2) Visitor mode can unify functions and can do reports, UI, interceptors and filters, and is suitable for systems with relatively stable data structures.

  • shortcoming

1) Specific elements publish details to visitors, which means that visitors pay attention to the internal details of other categories. This is not recommended by Dimit's Law, which makes it difficult to change specific elements.

2) Violates the dependency inversion principle. Visitors rely on concrete elements rather than abstract elements

3) Therefore, if a system has a relatively stable data structure and frequently changing functional requirements, then the visitor mode is more appropriate.

7. Understand

image-20210703211735411

Pass in the corresponding person implementation class through ObjectStrcure, call its accept(), and pass in the specific action implementation class;

The specific implementation class under Perosn, such as the Man class, calls the incoming action method in its accept() method and passes itself in (this)

That is, man calls accept() and passes in fail. The fail method is called in man's accept method. This fail method wants to pass in the man class, so it appears.双生派

  • Example of Zhang San and Li Si going to a massage parlor
想到了个例子:
张三和李四访问按摩店,寻找按摩店的技师
------------------------
把张三&李四抽象成Element抽象类,为Perosn抽象类;
Perosn抽象类里面有一个抽象方法:呼叫技师,call()方法
按摩店技师抽象成Visitor抽象类,访问者,也就是Technician抽象类;
Technician抽象类里面有:两个实现类,1、金油技师2、腿部技师
他们分别对应对张三按摩方法makeToZhangsan()、对李四按摩方法makeToLisi()
技师Technician抽象类,下面有两个实现,一个是金油技师oilTech类,一个是腿部技师LegsTech类;
他们会实现对应的对张三按摩方法makeToZhangsan()、对李四按摩方法makeToLisi(),并要求传入服务对象,也就是Zhansan类还是LisiPerson抽象类有两个实现类,一个是张三Zhansan类,一个是李四Lisi类,
他们实现call()方法,并作出了实现这个方法传入我们要叫的具体技师,如金油技师oilTech类,
在这个call()方法中调用对应技师的服务张三方法makeToZhansan()或对李四按摩方法makeToLisi()
--------------------------
最后在ObjectStructure,也就是对应的按摩中心的一个集合,里面有增加服务对象方法attch(),和移除服务对象方法detach(),都是传入对应服务对象;
通过这个集合来管理按摩中心的服务的人,如张三、李四
然后有一个服务方法make,去传入对应技师,然后遍历,调用对应里面服务服务对象的call()方法去呼唤技师。

Guess you like

Origin blog.csdn.net/qq_43409973/article/details/130588908