什么是访问者模式

访问者模式是一种将算法与对象结构分离的软件设计模式。

这个模式的基本想法如下:首先我们拥有一个由许多对象构成的对象结构,这些对象的类都拥有一个accept方法用来接受访问者对象;访问者是一个接口,它拥有一个visit方法,这个方法对访问到的对象结构中不同类型的元素作出不同的反应;在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施accept方法,在每一个元素的accept方法中回调访问者的visit方法,从而使访问者得以处理对象结构的每一个元素。我们可以针对对象结构设计不同的实在的访问者类来完成不同的操作。

访问者模式的结构

  • ObjectStructure:对象结构

  • Element:抽象元素

  • ConcreteElementA:具体元素A

  • ConcreteElementB:具体元素B

  • Visitor:抽象访问者

  • ConcreteVisitorA:具体访问者A

  • ConcreteVisitorB:具体访问者B

访问者模式的一个实例

Sunny软件公司欲为某高校开发一套奖励审批系统,该系统可以实现教师奖励和学生奖励的审批(Award Check),如果教师发表论文数超过10篇或者学生论文超过2篇可以评选科研奖,如果教师教学反馈分大于等于90分或者学生平均成绩大于等于90分可以评选成绩优秀奖。

实例代码

AwardCheck

public abstract class AwardCheck {
    public abstract void visit(Student student);
    public abstract void visit(Teacher teacher);
}

PointAward

public class PointAward extends AwardCheck {
    @Override
    public void visit(Student student) {
        if (student.getScore() >= 90){
            System.out.println("Student:[" + student.getName() + "] get PointAward.");
        }
    }

    @Override
    public void visit(Teacher teacher) {
        if (teacher.getScore() >= 90){
            System.out.println("Teacher:[" + teacher.getName() + "] get PointAward.");
        }
    }
}

TechAward

public class TechAward extends AwardCheck {
    @Override
    public void visit(Student student) {
        if (student.getPaper() > 1){
            System.out.println("Student:[" + student.getName() + "] get TechAward.");
        }
    }

    @Override
    public void visit(Teacher teacher) {
        if (teacher.getPaper() > 9){
            System.out.println("Teacher:[" + teacher.getName() + "] get TechAward.");
        }
    }
}

Member

public abstract class Member {
    public abstract void accept(AwardCheck handle);
}

Student

public class Student extends Member {

    private String name;
    private int paper;
    private int score;

    public Student(String name,int paper,int score){
        this.name = name;
        this.paper = paper;
        this.score = score;
    }

    @Override
    public void accept(AwardCheck handle) {
        handle.visit(this);
    }

    public String getName() {
        return name;
    }

    public int getPaper() {
        return paper;
    }

    public int getScore() {
        return score;
    }
}

Teacher

public class Teacher extends Member {

    private String name;
    private int paper;
    private int score;

    public Teacher(String name,int paper,int score){
        this.name = name;
        this.paper = paper;
        this.score = score;
    }

    @Override
    public void accept(AwardCheck handle) {
        handle.visit(this);
    }

    public String getName() {
        return name;
    }

    public int getPaper() {
        return paper;
    }

    public int getScore() {
        return score;
    }
}

MemberList

public class MemberList {
    private List<Member> members = new ArrayList<Member>();

    public void addMember(Member member){
        members.add(member);
    }

    public void accept(AwardCheck awardCheck){
        for (Member member:members){
            member.accept(awardCheck);
        }
    }
}

Client

public class Client {
    public static void main(String[] args){
        MemberList memberList = new MemberList();
        memberList.addMember(new Student("Jack",3,75));
        memberList.addMember(new Student("Lucy",1,98));
        memberList.addMember(new Student("Ben",0,60));

        memberList.addMember(new Teacher("Tal",13,67));
        memberList.addMember(new Teacher("Allen",19,99));
        memberList.addMember(new Teacher("Meisi",8,79));

        memberList.accept(new TechAward());
        memberList.accept(new PointAward());
    }
}

实例结果

Student:[Jack] get TechAward.
Teacher:[Tal] get TechAward.
Teacher:[Allen] get TechAward.
Student:[Lucy] get PointAward.
Teacher:[Allen] get PointAward.

(完)