JAVA23种设计模式之访问者模式

  1. 访问者模式
    访问者模式是对象的行为模式,访问者模式的目的是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改,接受这个操作的数据结构则保持不变。换句话说就是把数据结构和需要对该数据结构进行的操作分离处理,当需要对当前数据结构做新的操作时,只需要修改操作部分而不需要修改数据结构的代码。
  2. 访问者模式的示意图
    在这里插入图片描述
  3. 访问者模式所包含的角色
    抽象访问者角色: 一般是抽象类或者是接口,为系统中每个元素定义了访问行为,他的参数就是可以访问的元素,理论上来讲,这里面所包含的方法与元素个数是一样的。
    具体访问者角色:继承或者实现抽象访问角色,给出对每一个元素访问时所产生的行为。
    抽象元素角色:一般是抽象类或者接口,定义了一个接受访问这角色的方法,主要作用是做到每个元素都能被访问者访问。
    具体元素角色:继承或者事项抽象元素角色,实现接受访问的具体方法,一般是使用访问者提供的访问该元素类的方法。
    对象结构角色:一般用于管理元素集合,并且可以迭代这些元素工访问者访问
  4. 示例代码
    某系统可以实现教师奖励和学生奖励的审批(Award Check),如果教师发表论文数超过10篇或者学生论文超过2篇可以评选科研奖,如果教师教学反馈分大于等于90分或者学生平均成绩大于等于90分可以评选成绩优秀奖。试使用访问者模式设计该系统,以判断候选人集合中的教师或学生是否符合某种获奖要求。
  • 抽象访问者角色:
public interface Award {
        void visitorStudent(Student student);
        void vivitorTeacher(Teacher teacher);
}
  • 抽象元素角色:
public interface Person {
    void accept(Award award);
}
  • 具体元素角色:
    学生:
public class Student implements Person {
    private String name;
    private int numOfPaper;
    private float score;
    public Student(String name, int numOfPaper, float score) {
        this.name = name;
        this.numOfPaper = numOfPaper;
        this.score = score;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getNumOfPaper() {
        return numOfPaper;
    }
    public void setNumOfPaper(int numOfPaper) {
        this.numOfPaper = numOfPaper;
    }
    public float getScore() {
        return score;
    }
    public void setScore(float score) {
        this.score = score;
    }
    @Override
    public void accept(Award award) {
            award.visitorStudent(this);
    }
}

老师:

public class Teacher implements Person {
    private String name;
    private int numOfPaper;
    private float score;
    public Teacher(String name, int numOfPaper, float score) {
        this.name = name;
        this.numOfPaper = numOfPaper;
        this.score = score;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getNumOfPaper() {
        return numOfPaper;
    }
    public void setNumOfPaper(int numOfPaper) {
        this.numOfPaper = numOfPaper;
    }
    public float getScore() {
        return score;
    }
    public void setScore(float score) {
        this.score = score;
    }
    @Override
    public void accept(Award award) {
            award.vivitorTeacher(this);
    }
}

  • 具体访问者角色:
    科研奖:
public class AwardCheckOne implements Award {
    @Override
    public void visitorStudent(Student student) {
        int numOfPaper = student.getNumOfPaper();
        float score = student.getScore();
        String name = student.getName();
        if(numOfPaper>2){
            System.out.println("学生"+name+"可以评选科研奖!");
        }
    }
    @Override
    public void vivitorTeacher(Teacher teacher) {
            int numOfPaper = teacher.getNumOfPaper();
            float score = teacher.getScore();
            String name = teacher.getName();
        if(numOfPaper>10){
            System.out.println("老师"+name+"可以评选科研奖!");
        }
    }
}

成绩优秀奖:

public class AwardCheckTwo implements Award {
    @Override
    public void visitorStudent(Student student) {
        int numOfPaper = student.getNumOfPaper();
        float score = student.getScore();
        String name = student.getName();
        if(score>=90){
            System.out.println("学生"+name+"可以评选成绩优秀奖!");
        }
    }
    @Override
    public void vivitorTeacher(Teacher teacher) {
        int numOfPaper = teacher.getNumOfPaper();
        float score = teacher.getScore();
        String name = teacher.getName();
        if(score>=90){
            System.out.println("老师"+name+"可以评选成绩优秀奖!");
        }
    }
}
  • 对象结构角色:
public class PersonList {
    private ArrayList<Person> personArrayList = null;

    public PersonList() {
        personArrayList = new ArrayList<Person>();
    }

    public void addPerson(Person person){
        personArrayList.add(person);
    }

    //遍历访问 集合中的每一个对象
    public void accept(Award award) {
        for(Object obj : personArrayList){
            ((Person)obj).accept(award);
        }
    }
}
  • 测试方法:
public class Main {
    public static void main(String[] args) {
        PersonList personList = new PersonList();
        Person p1,p2,p3,p4;
        p1 = new Student("张三",1,80);
        p2 = new Student("李四",3,100);
        p3 = new Teacher("王五",9,100);
        p4 = new Teacher("呜呜呜",11,100);
        personList.addPerson(p1);
        personList.addPerson(p2);
        personList.addPerson(p3);
        personList.addPerson(p4);
        personList.accept(new AwardCheckOne());

        System.out.println("---------------分界线--------------------");

        personList.accept(new AwardCheckTwo());
    }
}
  • 运行截图:
    在这里插入图片描述
  1. 访问者模式的优缺点:
    优点:符合单一职责原则,使得数据对象和操作解耦;添加新的操作或者新的访问者变得很容易,具有良好的可扩展性;相对来说更加具有灵活性和复用性。
    缺点:增加新的元素变得困难,在该模式中,每增加一个新的元素,都要修改抽象访问这角色,违背了开闭原则。破坏了封装性,访问者模式要求访问者对象访问并调用每一个元素对象的操作,这意味着元素对象有时候必须暴露一些自己的内部操作和内部状态,否则无法供访问者访问。
发布了62 篇原创文章 · 获赞 8 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/system_obj/article/details/88587101