访问者模式是一种行为设计模式,它允许在不修改对象结构的情况下向类的实例添加新操作。这种模式通常用于处理具有层次结构的复杂数据集。在访问者模式中,有一个表示元素的接口,以及一个或多个实现了该接口的具体元素类。还有一个表示访问者的接口,以及一个实现了该接口的具体访问者类。访问者通过调用元素的方法来访问元素。,,观察者模式是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。观察者模式通常用于实现事件驱动的系统。在观察者模式中,有一个主题(Subject)类,它是所有观察者(Observer)的容器。当主题的状态发生改变时,它会通知所有观察者。观察者则负责处理主题状态改变的通知。
在计算机科学中,设计模式是一种被广泛接受并应用于各种软件开发领域的优秀解决方案,它们提供了一种可重用的、经过验证的方法来解决常见的问题,本文将详细介绍访问者模式这一设计模式,并通过一个实际的编程示例来展示其应用。
访问者模式(Visitor Pattern)是一种行为型设计模式,它定义了一种处理对象结构中的元素的接口,使得你可以在不改变数据结构的前提下添加新的操作,这种模式主要解决了在处理一个聚合对象时,需要对其中包含的类进行操作的问题。
访问者模式的主要角色有以下几个:
1、抽象访问者(AbstractVisitor):定义了访问具体元素的操作,但不包含任何操作的具体实现。
2、具体访问者(ConcreteVisitor):实现了抽象访问者的抽象方法,提供了具体的操作实现。
3、抽象元素(AbstractElement):定义了接受访问者的具体方法,但不包含任何操作的具体实现。
4、具体元素(ConcreteElement):实现了抽象元素的抽象方法,提供了具体的操作实现。
5、客户端(Client):负责创建具体元素和具体访问者,并将它们连接起来。
下面我们通过一个简单的示例来说明访问者模式的应用:
假设我们有一个表示学生的类Student
,以及一个表示课程的类Course
,每个学生可以选修多门课程,而每门课程又可以被多个学生选修,现在我们需要计算每个学生所选修课程的总学分。
我们定义Student
和Course
类:
public abstract class Element { public abstract void accept(Visitor visitor); } public class Student extends Element { private String name; private List<Course> courses; public Student(String name) { this.name = name; this.courses = new ArrayList<>(); } public void addCourse(Course course) { courses.add(course); } @Override public void accept(Visitor visitor) { visitor.visitStudent(this); } } public class Course extends Element { private String name; private int credit; public Course(String name, int credit) { this.name = name; this.credit = credit; } }
我们定义ScoreVisitor
类,用于计算学生的总学分:
public class ScoreVisitor extends AbstractVisitor { private int totalCredit; @Override public void visitStudent(Student student) { totalCredit = 0; for (Course course : student.getCourses()) { course.accept(this); } } @Override public int getTotalCredit() { return totalCredit; } }
我们在客户端代码中使用访问者模式:
public class Client { public static void main(String[] args) { Student student1 = new Student("张三"); student1.addCourse(new Course("数学", 4)); student1.addCourse(new Course("英语", 3)); student1.addCourse(new Course("计算机", 2)); Student student2 = new Student("李四"); student2.addCourse(new Course("数学", 3)); student2.addCourse(new Course("英语", 4)); student2.addCourse(new Course("物理", 3)); ScoreVisitor scoreVisitor = new ScoreVisitor(); student1.accept(scoreVisitor); // 张三的总学分为10分(4+3+2=9分) + 李四的总学分为9分 + 其他学生的总学分 = 总学分18分 + 其他学生的总学分 = 总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)=总学分18分 + (0+0+0)+其他学生的总学分=总学分18+(其他学生的总学分)+(其他学生的总学分)+......+(其他学生的总学分)=所有学生总学分之和